package admin

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	appcfg "github.com/gothinkster/golang-gin-realworld-example-app/config"
	"github.com/gothinkster/golang-gin-realworld-example-app/common"
	"github.com/gothinkster/golang-gin-realworld-example-app/lending"
	"github.com/gothinkster/golang-gin-realworld-example-app/models"
)

// ── Collateral Buyer Bot ───────────────────────────────────────────────────

func GetBuyerBotStatus(c *gin.Context) {
	OK(c, lending.GetBuyerBotStatus())
}

func StartBuyerBot(c *gin.Context) {
	cfg := appcfg.AppConfig
	if cfg == nil {
		Fail(c, http.StatusInternalServerError, "Configuration not loaded")
		return
	}
	if cfg.CollateralBuyerPrivateKey == "" {
		Fail(c, http.StatusBadRequest, "COLLATERAL_BUYER_PRIVATE_KEY not configured on server")
		return
	}
	lending.StartCollateralBuyerBot(cfg)
	OK(c, gin.H{"message": "Collateral buyer bot start signal sent"})
}

func StopBuyerBot(c *gin.Context) {
	lending.StopCollateralBuyerBot()
	OK(c, gin.H{"message": "Collateral buyer bot stop signal sent"})
}

func ListBuyRecords(c *gin.Context) {
	db := common.GetDB()
	p := ParsePagination(c)

	query := db.Model(&models.CollateralBuyRecord{})
	if v := c.Query("chain_id"); v != "" {
		if id, err := strconv.Atoi(v); err == nil {
			query = query.Where("chain_id = ?", id)
		}
	}
	if v := c.Query("status"); v != "" {
		query = query.Where("status = ?", v)
	}
	if v := c.Query("asset_addr"); v != "" {
		query = query.Where("asset_addr = ?", v)
	}

	var total int64
	query.Count(&total)

	var records []models.CollateralBuyRecord
	if err := query.Order("created_at DESC").Offset(p.Offset()).Limit(p.PageSize).Find(&records).Error; err != nil {
		Fail(c, http.StatusInternalServerError, "Failed to fetch buy records")
		return
	}
	OKList(c, records, total)
}

// GetLiquidationStatus returns the current liquidation bot status
func GetLiquidationStatus(c *gin.Context) {
	status := lending.GetBotStatus()
	OK(c, status)
}

// StartLiquidationBot starts the liquidation bot
func StartLiquidationBot(c *gin.Context) {
	cfg := appcfg.AppConfig
	if cfg == nil {
		Fail(c, http.StatusInternalServerError, "Configuration not loaded")
		return
	}
	if cfg.LiquidatorPrivateKey == "" {
		Fail(c, http.StatusBadRequest, "LIQUIDATOR_PRIVATE_KEY not configured on server")
		return
	}
	lending.StartLiquidationBot(cfg)
	OK(c, gin.H{"message": "Liquidation bot start signal sent"})
}

// StopLiquidationBot stops the liquidation bot
func StopLiquidationBot(c *gin.Context) {
	lending.StopLiquidationBot()
	OK(c, gin.H{"message": "Liquidation bot stop signal sent"})
}

// ListLiquidationRecords returns paginated liquidation history
func ListLiquidationRecords(c *gin.Context) {
	db := common.GetDB()
	p := ParsePagination(c)

	query := db.Model(&models.LiquidationRecord{})
	if v := c.Query("chain_id"); v != "" {
		if id, err := strconv.Atoi(v); err == nil {
			query = query.Where("chain_id = ?", id)
		}
	}
	if v := c.Query("status"); v != "" {
		query = query.Where("status = ?", v)
	}
	if v := c.Query("liquidator_addr"); v != "" {
		query = query.Where("liquidator_addr = ?", v)
	}

	var total int64
	query.Count(&total)

	var records []models.LiquidationRecord
	if err := query.Order("created_at DESC").Offset(p.Offset()).Limit(p.PageSize).Find(&records).Error; err != nil {
		Fail(c, http.StatusInternalServerError, "Failed to fetch liquidation records")
		return
	}
	OKList(c, records, total)
}
