package admin

import (
	"fmt"
	"verification-platform-backend/internal/database"
	"verification-platform-backend/internal/model"
	"verification-platform-backend/internal/service"
	"verification-platform-backend/pkg/response"

	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
)

func SetupAgentsRoutes(r *gin.RouterGroup) {
	agents := r.Group("/agents")
	{
		agents.GET("", handleGetAgents)
		agents.GET("/tree", handleGetAgentsTree)
		agents.POST("", handleCreateAgent)
		agents.GET("/:id", handleGetAgentDetail)
		agents.PUT("/:id", handleUpdateAgent)
		agents.PUT("/:id/status", handleUpdateAgentStatus)
		agents.DELETE("/:id", handleDeleteAgent)
		agents.GET("/:id/cards", handleGetAgentCards)
		agents.PUT("/:id/cards", handleUpdateAgentCards)
		agents.POST("/batch/status", handleBatchUpdateAgentStatus)
		agents.DELETE("/batch", handleBatchDeleteAgents)
	}
}

type AgentTreeNode struct {
	ID               uint            `json:"id"`
	Username         string          `json:"username"`
	Email            string          `json:"email"`
	Avatar           string          `json:"avatar"`
	Status           string          `json:"status"`
	Role             string          `json:"role"`
	ParentAgentID    *uint           `json:"parent_agent_id"`
	ParentAgentName  string          `json:"parent_agent_name"`
	CreatedAt        string          `json:"created_at"`
	LastLoginAt      string          `json:"last_login_at"`
	Balance          float64         `json:"balance"`
	CanCreateAgent   bool            `json:"can_create_agent"`
	CardsCount       int             `json:"cards_count"`
	ChildAgentsCount int             `json:"child_agents_count"`
	Children         []AgentTreeNode `json:"children,omitempty"`
}

func handleGetAgents(c *gin.Context) {
	var users []model.User
	if err := database.DB.Where("role = ?", "agent").
		Preload("ParentAgent").
		Order("created_at DESC").
		Find(&users).Error; err != nil {
		response.Error(c, 500, "获取代理列表失败")
		return
	}

	type AgentResponse struct {
		ID               uint    `json:"id"`
		Username         string  `json:"username"`
		Email            string  `json:"email"`
		Avatar           string  `json:"avatar"`
		Status           string  `json:"status"`
		Role             string  `json:"role"`
		ParentAgentID    *uint   `json:"parent_agent_id"`
		ParentAgentName  string  `json:"parent_agent_name"`
		CreatedAt        string  `json:"created_at"`
		LastLoginAt      string  `json:"last_login_at"`
		Balance          float64 `json:"balance"`
		CanCreateAgent   bool    `json:"can_create_agent"`
		CardsCount       int     `json:"cards_count"`
		ChildAgentsCount int     `json:"child_agents_count"`
	}

	var result []AgentResponse
	for _, user := range users {
		var parentAgentName string
		if user.ParentAgent != nil {
			parentAgentName = user.ParentAgent.Username
		}

		var childAgentsCount int64
		database.DB.Model(&model.User{}).Where("parent_agent_id = ?", user.ID).Count(&childAgentsCount)

		var cardsCount int64
		database.DB.Model(&model.Card{}).Where("creator_id = ?", user.ID).Count(&cardsCount)

		var lastLoginAt string
		if user.LastLoginAt != nil {
			lastLoginAt = user.LastLoginAt.Format("2006-01-02 15:04:05")
		}

		email := ""
		if user.Email != nil {
			email = *user.Email
		}

		result = append(result, AgentResponse{
			ID:               user.ID,
			Username:         user.Username,
			Email:            email,
			Avatar:           user.Avatar,
			Status:           user.Status,
			Role:             user.Role,
			ParentAgentID:    user.ParentAgentID,
			ParentAgentName:  parentAgentName,
			CreatedAt:        user.CreatedAt.Format("2006-01-02 15:04:05"),
			LastLoginAt:      lastLoginAt,
			Balance:          user.Balance,
			CanCreateAgent:   user.CanCreateAgent,
			CardsCount:       int(cardsCount),
			ChildAgentsCount: int(childAgentsCount),
		})
	}

	response.Success(c, gin.H{
		"agents": result,
		"total":  len(result),
	})
}

func handleGetAgentsTree(c *gin.Context) {
	var users []model.User
	if err := database.DB.Where("role = ?", "agent").
		Preload("ParentAgent").
		Order("created_at DESC").
		Find(&users).Error; err != nil {
		response.Error(c, 500, "获取代理列表失败")
		return
	}

	userMap := make(map[uint]model.User)
	for _, user := range users {
		userMap[user.ID] = user
	}

	childrenMap := make(map[uint][]uint)
	var rootUsers []uint
	for _, user := range users {
		if user.ParentAgentID != nil {
			childrenMap[*user.ParentAgentID] = append(childrenMap[*user.ParentAgentID], user.ID)
		} else {
			rootUsers = append(rootUsers, user.ID)
		}
	}

	var buildTree func(userID uint) AgentTreeNode
	buildTree = func(userID uint) AgentTreeNode {
		user := userMap[userID]

		var parentAgentName string
		if user.ParentAgent != nil {
			parentAgentName = user.ParentAgent.Username
		}

		var cardsCount int64
		database.DB.Model(&model.Card{}).Where("creator_id = ?", user.ID).Count(&cardsCount)

		var childAgentsCount int64
		database.DB.Model(&model.User{}).Where("parent_agent_id = ?", user.ID).Count(&childAgentsCount)

		var lastLoginAt string
		if user.LastLoginAt != nil {
			lastLoginAt = user.LastLoginAt.Format("2006-01-02 15:04:05")
		}

		email := ""
		if user.Email != nil {
			email = *user.Email
		}

		node := AgentTreeNode{
			ID:               user.ID,
			Username:         user.Username,
			Email:            email,
			Avatar:           user.Avatar,
			Status:           user.Status,
			Role:             user.Role,
			ParentAgentID:    user.ParentAgentID,
			ParentAgentName:  parentAgentName,
			CreatedAt:        user.CreatedAt.Format("2006-01-02 15:04:05"),
			LastLoginAt:      lastLoginAt,
			Balance:          user.Balance,
			CanCreateAgent:   user.CanCreateAgent,
			CardsCount:       int(cardsCount),
			ChildAgentsCount: int(childAgentsCount),
		}

		if childIDs, exists := childrenMap[userID]; exists {
			for _, childID := range childIDs {
				node.Children = append(node.Children, buildTree(childID))
			}
		}

		return node
	}

	var tree []AgentTreeNode
	for _, rootID := range rootUsers {
		tree = append(tree, buildTree(rootID))
	}

	response.Success(c, gin.H{
		"tree":  tree,
		"total": len(users),
	})
}

func handleCreateAgent(c *gin.Context) {
	var req struct {
		Username       string  `json:"username" binding:"required"`
		Email          string  `json:"email"`
		Password       string  `json:"password" binding:"required"`
		ParentAgentID  *uint   `json:"parent_agent_id"`
		CanCreateAgent bool    `json:"can_create_agent"`
		Balance        float64 `json:"balance"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	var existingUser model.User
	if err := database.DB.Where("username = ?", req.Username).First(&existingUser).Error; err == nil {
		response.Error(c, 400, "用户名已存在")
		return
	}

	if req.Email != "" {
		if err := database.DB.Where("email = ?", req.Email).First(&existingUser).Error; err == nil {
			response.Error(c, 400, "邮箱已被使用")
			return
		}
	}

	if req.ParentAgentID != nil {
		var parentAgent model.User
		if err := database.DB.Where("id = ? AND role = ?", *req.ParentAgentID, "agent").First(&parentAgent).Error; err != nil {
			response.Error(c, 404, "上级代理不存在")
			return
		}
	}

	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		response.Error(c, 500, "密码加密失败")
		return
	}

	user := model.User{
		Username:       req.Username,
		Password:       string(hashedPassword),
		Role:           "agent",
		Status:         "active",
		ParentAgentID:  req.ParentAgentID,
		CanCreateAgent: req.CanCreateAgent,
		Balance:        req.Balance,
	}

	if req.Email != "" {
		user.Email = &req.Email
	}

	if err := database.DB.Create(&user).Error; err != nil {
		response.Error(c, 500, "创建代理失败")
		return
	}

	service.LogOperation(c, "create", "agent", &user.ID, fmt.Sprintf("创建代理: %s", user.Username), nil)

	response.Success(c, gin.H{
		"id":       user.ID,
		"username": user.Username,
	})
}

func handleGetAgentDetail(c *gin.Context) {
	agentID := c.Param("id")

	var user model.User
	if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").
		Preload("ParentAgent").
		First(&user).Error; err != nil {
		response.Error(c, 404, "代理不存在")
		return
	}

	var agentApps []model.AgentApplication
	database.DB.Where("agent_id = ?", user.ID).
		Preload("Application").
		Find(&agentApps)

	var childAgents []model.User
	database.DB.Where("parent_agent_id = ?", user.ID).Find(&childAgents)

	var cards []model.Card
	database.DB.Where("creator_id = ?", user.ID).
		Preload("Application").
		Preload("CardType").
		Find(&cards)

	type CardResponse struct {
		ID            uint    `json:"id"`
		CardKey       string  `json:"card_key"`
		ApplicationID uint    `json:"application_id"`
		AppName       string  `json:"app_name"`
		CardTypeID    uint    `json:"card_type_id"`
		CardTypeName  string  `json:"card_type_name"`
		Price         float64 `json:"price"`
		Status        string  `json:"status"`
		CreatedAt     string  `json:"created_at"`
	}

	var cardsResponse []CardResponse
	for _, card := range cards {
		appName := ""
		if card.Application != nil {
			appName = card.Application.Name
		}
		cardTypeName := ""
		if card.CardType.ID != 0 {
			cardTypeName = card.CardType.Name
		}
		cardsResponse = append(cardsResponse, CardResponse{
			ID:            card.ID,
			CardKey:       card.CardKey,
			ApplicationID: card.ApplicationID,
			AppName:       appName,
			CardTypeID:    card.CardTypeID,
			CardTypeName:  cardTypeName,
			Price:         card.CardType.Price,
			Status:        card.Status,
			CreatedAt:     card.CreatedAt.Format("2006-01-02 15:04:05"),
		})
	}

	var lastLoginAt string
	if user.LastLoginAt != nil {
		lastLoginAt = user.LastLoginAt.Format("2006-01-02 15:04:05")
	}

	email := ""
	if user.Email != nil {
		email = *user.Email
	}

	var parentAgentName string
	if user.ParentAgent != nil {
		parentAgentName = user.ParentAgent.Username
	}

	response.Success(c, gin.H{
		"id":                 user.ID,
		"username":           user.Username,
		"email":              email,
		"avatar":             user.Avatar,
		"status":             user.Status,
		"role":               user.Role,
		"parent_agent_id":    user.ParentAgentID,
		"parent_agent_name":  parentAgentName,
		"can_create_agent":   user.CanCreateAgent,
		"balance":            user.Balance,
		"created_at":         user.CreatedAt.Format("2006-01-02 15:04:05"),
		"last_login_at":      lastLoginAt,
		"cards":              cardsResponse,
		"cards_count":        len(cardsResponse),
		"child_agents_count": len(childAgents),
	})
}

func handleUpdateAgent(c *gin.Context) {
	agentID := c.Param("id")

	var user model.User
	if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil {
		response.Error(c, 404, "代理不存在")
		return
	}

	var req struct {
		ParentAgentID  *uint    `json:"parent_agent_id"`
		Email          *string  `json:"email"`
		Password       *string  `json:"password"`
		CanCreateAgent *bool    `json:"can_create_agent"`
		Balance        *float64 `json:"balance"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	if req.ParentAgentID != nil {
		if *req.ParentAgentID == user.ID {
			response.Error(c, 400, "不能将自己设为上级代理")
			return
		}
		var parentAgent model.User
		if err := database.DB.Where("id = ? AND role = ?", *req.ParentAgentID, "agent").First(&parentAgent).Error; err != nil {
			response.Error(c, 404, "上级代理不存在")
			return
		}
		user.ParentAgentID = req.ParentAgentID
	}

	if req.Email != nil {
		user.Email = req.Email
	}
	if req.Password != nil && *req.Password != "" {
		hashedPassword, err := bcrypt.GenerateFromPassword([]byte(*req.Password), bcrypt.DefaultCost)
		if err != nil {
			response.Error(c, 500, "密码加密失败")
			return
		}
		user.Password = string(hashedPassword)
	}
	if req.CanCreateAgent != nil {
		user.CanCreateAgent = *req.CanCreateAgent
	}
	if req.Balance != nil {
		user.Balance = *req.Balance
	}

	if err := database.DB.Save(&user).Error; err != nil {
		response.Error(c, 500, "更新失败")
		return
	}

	service.LogOperation(c, "update", "agent", &user.ID, fmt.Sprintf("更新代理: %s", user.Username), nil)

	response.Success(c, gin.H{
		"id": user.ID,
	})
}

func handleUpdateAgentStatus(c *gin.Context) {
	agentID := c.Param("id")

	var user model.User
	if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil {
		response.Error(c, 404, "代理不存在")
		return
	}

	var req struct {
		Status string `json:"status" binding:"required,oneof=active inactive banned"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	user.Status = req.Status
	if err := database.DB.Save(&user).Error; err != nil {
		response.Error(c, 500, "更新状态失败")
		return
	}

	service.LogOperation(c, "update_status", "agent", &user.ID, fmt.Sprintf("更新代理状态: %s -> %s", user.Username, user.Status), nil)

	response.Success(c, gin.H{
		"id":     user.ID,
		"status": user.Status,
	})
}

func handleDeleteAgent(c *gin.Context) {
	agentID := c.Param("id")

	var user model.User
	if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil {
		response.Error(c, 404, "代理不存在")
		return
	}

	database.DB.Model(&model.User{}).Where("parent_agent_id = ?", user.ID).Update("parent_agent_id", nil)

	if err := database.DB.Delete(&user).Error; err != nil {
		response.Error(c, 500, "删除失败")
		return
	}

	service.LogOperation(c, "delete", "agent", &user.ID, fmt.Sprintf("删除代理: %s", user.Username), nil)

	response.Success(c, gin.H{
		"id": user.ID,
	})
}

func handleGetAgentCards(c *gin.Context) {
	agentID := c.Param("id")

	var user model.User
	if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil {
		response.Error(c, 404, "代理不存在")
		return
	}

	var cards []model.Card
	database.DB.Where("creator_id = ?", user.ID).
		Preload("Application").
		Preload("CardType").
		Order("created_at DESC").
		Find(&cards)

	type CardResponse struct {
		ID            uint    `json:"id"`
		CardKey       string  `json:"card_key"`
		ApplicationID uint    `json:"application_id"`
		AppName       string  `json:"app_name"`
		CardTypeID    uint    `json:"card_type_id"`
		CardTypeName  string  `json:"card_type_name"`
		Price         float64 `json:"price"`
		Status        string  `json:"status"`
		CreatedAt     string  `json:"created_at"`
	}

	var result []CardResponse
	for _, card := range cards {
		appName := ""
		if card.Application != nil {
			appName = card.Application.Name
		}
		cardTypeName := ""
		if card.CardType.ID != 0 {
			cardTypeName = card.CardType.Name
		}
		result = append(result, CardResponse{
			ID:            card.ID,
			CardKey:       card.CardKey,
			ApplicationID: card.ApplicationID,
			AppName:       appName,
			CardTypeID:    card.CardTypeID,
			CardTypeName:  cardTypeName,
			Price:         card.CardType.Price,
			Status:        card.Status,
			CreatedAt:     card.CreatedAt.Format("2006-01-02 15:04:05"),
		})
	}

	response.Success(c, gin.H{
		"cards": result,
		"total": len(result),
	})
}

func handleUpdateAgentCards(c *gin.Context) {
	agentID := c.Param("id")

	var user model.User
	if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil {
		response.Error(c, 404, "代理不存在")
		return
	}

	var req struct {
		Cards []struct {
			CardID uint   `json:"card_id"`
			Status string `json:"status"`
		} `json:"cards"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	for _, cardReq := range req.Cards {
		database.DB.Model(&model.Card{}).
			Where("id = ? AND creator_id = ?", cardReq.CardID, user.ID).
			Update("status", cardReq.Status)
	}

	response.Success(c, gin.H{
		"message": "更新成功",
	})
}

func handleBatchUpdateAgentStatus(c *gin.Context) {
	var req struct {
		AgentIDs []uint `json:"agent_ids" binding:"required"`
		Status   string `json:"status" binding:"required,oneof=active inactive banned"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	if len(req.AgentIDs) == 0 {
		response.Error(c, 400, "请选择要操作的代理")
		return
	}

	if err := database.DB.Model(&model.User{}).
		Where("id IN ? AND role = ?", req.AgentIDs, "agent").
		Update("status", req.Status).Error; err != nil {
		response.Error(c, 500, "批量更新状态失败")
		return
	}

	service.LogOperation(c, "batch_update_status", "agent", nil, fmt.Sprintf("批量更新代理状态: %d个代理 -> %s", len(req.AgentIDs), req.Status), nil)

	response.Success(c, gin.H{
		"updated": len(req.AgentIDs),
	})
}

func handleBatchDeleteAgents(c *gin.Context) {
	var req struct {
		AgentIDs []uint `json:"agent_ids" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	if len(req.AgentIDs) == 0 {
		response.Error(c, 400, "请选择要删除的代理")
		return
	}

	for _, agentID := range req.AgentIDs {
		var user model.User
		if err := database.DB.Where("id = ? AND role = ?", agentID, "agent").First(&user).Error; err != nil {
			continue
		}

		database.DB.Model(&model.User{}).Where("parent_agent_id = ?", user.ID).Update("parent_agent_id", nil)
		database.DB.Delete(&user)
	}

	service.LogOperation(c, "batch_delete", "agent", nil, fmt.Sprintf("批量删除代理: %d个", len(req.AgentIDs)), nil)

	response.Success(c, gin.H{
		"deleted": len(req.AgentIDs),
	})
}
