package admin

import (
	"fmt"
	"log"
	"time"

	"verification-platform-backend/internal/database"
	"verification-platform-backend/internal/model"
	"verification-platform-backend/pkg/response"

	"github.com/gin-gonic/gin"
)

func SetupAgentAppRoutes(r *gin.RouterGroup) {
	agentApps := r.Group("/agent-apps")
	{
		agentApps.GET("", handleGetAgentApps)
		agentApps.GET("/requests", handleGetAgentRequests)
		agentApps.POST("/invite", handleInviteAgent)
		agentApps.PUT("/requests/:id/approve", handleApproveRequest)
		agentApps.PUT("/requests/:id/reject", handleRejectRequest)
		agentApps.GET("/:id", handleGetAgentAppDetail)
		agentApps.PUT("/:id", handleUpdateAgentApp)
		agentApps.PUT("/:id/card-types", handleUpdateAgentCardTypes)
		agentApps.DELETE("/:id", handleRemoveAgentApp)
	}
}

func SetupAgentAppRoutesWithoutPackage(r *gin.RouterGroup) {
	agentApps := r.Group("/agent-apps")
	{
		agentApps.GET("/my-requests", handleGetMyRequests)
		agentApps.POST("/request", handleRequestAuthorization)
		agentApps.DELETE("/requests/:id", handleCancelRequest)
	}
}

func checkAgentPermission(userID uint) bool {
	var user model.User
	if err := database.DB.First(&user, userID).Error; err != nil {
		return false
	}

	if user.CurrentPackageID == nil {
		return false
	}

	var userPackage model.UserPackage
	if err := database.DB.Where("user_id = ? AND package_id = ? AND status = ?",
		userID, user.CurrentPackageID, "active").First(&userPackage).Error; err != nil {
		return false
	}

	if userPackage.ExpiredAt != nil && userPackage.ExpiredAt.Before(time.Now()) {
		return false
	}

	var permission model.PackagePermission
	if err := database.DB.Where("package_id = ?", user.CurrentPackageID).First(&permission).Error; err != nil {
		return false
	}

	return permission.AllowAgent
}

func handleGetAgentApps(c *gin.Context) {
	userID := c.GetUint("user_id")
	log.Printf("[DEBUG] handleGetAgentApps called for Admin %d\n", userID)

	var myAuthorizations []model.AgentApplication
	if err := database.DB.Where("admin_id = ?", userID).
		Preload("CardTypes.CardType").
		Find(&myAuthorizations).Error; err != nil {
		response.Error(c, 500, "获取授权列表失败")
		return
	}

	var receivedAuthorizations []model.AgentApplication
	if err := database.DB.Where("agent_id = ?", userID).
		Preload("CardTypes.CardType").
		Find(&receivedAuthorizations).Error; err != nil {
		response.Error(c, 500, "获取授权列表失败")
		return
	}

	log.Printf("[DEBUG] Found %d my authorizations and %d received authorizations for Admin %d\n",
		len(myAuthorizations), len(receivedAuthorizations), userID)

	var allAgentApps []model.AgentApplication
	allAgentApps = append(allAgentApps, myAuthorizations...)
	allAgentApps = append(allAgentApps, receivedAuthorizations...)

	var agentIDs []uint
	var AdminIDs []uint
	var applicationIDs []uint

	for _, aa := range allAgentApps {
		agentIDs = append(agentIDs, aa.AgentID)
		AdminIDs = append(AdminIDs, aa.AdminID)
		applicationIDs = append(applicationIDs, aa.ApplicationID)
	}

	var users []model.User
	if err := database.DB.Where("id IN ?", append(agentIDs, AdminIDs...)).Find(&users).Error; err != nil {
		log.Printf("[ERROR] Failed to query users: %v\n", err)
	} else {
		log.Printf("[DEBUG] Found %d users\n", len(users))
	}

	var applications []model.Application
	if err := database.DB.Where("id IN ?", applicationIDs).Find(&applications).Error; err != nil {
		log.Printf("[ERROR] Failed to query applications: %v\n", err)
	}

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

	applicationMap := make(map[uint]model.Application)
	for _, app := range applications {
		applicationMap[app.ID] = app
	}

	type CardTypeResponse struct {
		ID          uint   `json:"id"`
		CardTypeID  uint   `json:"card_type_id"`
		Name        string `json:"name"`
		CanGenerate bool   `json:"can_generate"`
	}

	type AgentAppResponse struct {
		ID            uint               `json:"id"`
		AgentID       uint               `json:"agent_id"`
		AgentName     string             `json:"agent_name"`
		AgentEmail    string             `json:"agent_email"`
		ApplicationID uint               `json:"application_id"`
		AppName       string             `json:"app_name"`
		Discount      float64            `json:"discount"`
		Status        string             `json:"status"`
		CardTypes     []CardTypeResponse `json:"card_types"`
		CreatedAt     string             `json:"created_at"`
		IsReceived    bool               `json:"is_received"`
	}

	var result []AgentAppResponse
	for _, aa := range allAgentApps {
		agentName := ""
		agentEmail := ""
		if user, exists := userMap[aa.AgentID]; exists {
			agentName = user.Username
			if user.Email != nil {
				agentEmail = *user.Email
			}
		}

		appName := ""
		if app, exists := applicationMap[aa.ApplicationID]; exists {
			appName = app.Name
		}

		var cardTypes []CardTypeResponse
		for _, ct := range aa.CardTypes {
			cardTypes = append(cardTypes, CardTypeResponse{
				ID:          ct.ID,
				CardTypeID:  ct.CardTypeID,
				Name:        ct.CardType.Name,
				CanGenerate: ct.CanGenerate,
			})
		}

		log.Printf("[DEBUG] Processing AgentApp: ID=%d, AgentID=%d, ApplicationID=%d, CardTypes count=%d, IsReceived=%v\n",
			aa.ID, aa.AgentID, aa.ApplicationID, len(cardTypes), aa.AgentID == userID)

		result = append(result, AgentAppResponse{
			ID:            aa.ID,
			AgentID:       aa.AgentID,
			AgentName:     agentName,
			AgentEmail:    agentEmail,
			ApplicationID: aa.ApplicationID,
			AppName:       appName,
			Discount:      aa.Discount,
			Status:        aa.Status,
			CardTypes:     cardTypes,
			CreatedAt:     aa.CreatedAt.Format("2006-01-02 15:04:05"),
			IsReceived:    aa.AgentID == userID,
		})
	}

	log.Printf("[DEBUG] Returning %d agent apps for user %d\n", len(result), userID)
	response.Success(c, gin.H{
		"agent_apps": result,
		"total":      len(result),
	})
}

func handleGetAgentRequests(c *gin.Context) {
	userID := c.GetUint("user_id")
	requestType := c.Query("type")

	query := database.DB.Where("admin_id = ?", userID)
	if requestType == "invite" {
		query = query.Where("type = ?", "invite")
	} else if requestType == "request" {
		query = query.Where("type = ?", "request")
	}

	var requests []model.AgentApplicationRequest
	if err := query.
		Preload("Agent").
		Preload("Application").
		Order("created_at DESC").
		Find(&requests).Error; err != nil {
		response.Error(c, 500, "获取申请列表失败")
		return
	}

	type RequestResponse struct {
		ID            uint   `json:"id"`
		AgentID       uint   `json:"agent_id"`
		AgentName     string `json:"agent_name"`
		AgentEmail    string `json:"agent_email"`
		AdminID   uint   `json:"admin_id"`
		ApplicationID uint   `json:"application_id"`
		AppName       string `json:"app_name"`
		Type          string `json:"type"`
		Status        string `json:"status"`
		Message       string `json:"message"`
		RejectReason  string `json:"reject_reason"`
		CreatedAt     string `json:"created_at"`
	}

	var result []RequestResponse
	for _, req := range requests {
		agentName := ""
		agentEmail := ""
		if req.Agent.ID != 0 {
			agentName = req.Agent.Username
			if req.Agent.Email != nil {
				agentEmail = *req.Agent.Email
			}
		}

		appName := ""
		if req.Application.ID != 0 {
			appName = req.Application.Name
		}

		result = append(result, RequestResponse{
			ID:            req.ID,
			AgentID:       req.AgentID,
			AgentName:     agentName,
			AgentEmail:    agentEmail,
			AdminID:   req.AdminID,
			ApplicationID: req.ApplicationID,
			AppName:       appName,
			Type:          req.Type,
			Status:        req.Status,
			Message:       req.Message,
			RejectReason:  req.RejectReason,
			CreatedAt:     req.CreatedAt.Format("2006-01-02 15:04:05"),
		})
	}

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

func handleGetMyRequests(c *gin.Context) {
	userID := c.GetUint("user_id")
	requestType := c.Query("type")

	query := database.DB.Where("agent_id = ?", userID)
	if requestType == "invite" {
		query = query.Where("type = ?", "invite")
	} else if requestType == "request" {
		query = query.Where("type = ?", "request")
	}

	var requests []model.AgentApplicationRequest
	if err := query.
		Preload("Admin").
		Preload("Application").
		Order("created_at DESC").
		Find(&requests).Error; err != nil {
		response.Error(c, 500, "获取申请列表失败")
		return
	}

	type RequestResponse struct {
		ID            uint   `json:"id"`
		AgentID       uint   `json:"agent_id"`
		AdminID   uint   `json:"admin_id"`
		AdminName string `json:"admin_name"`
		ApplicationID uint   `json:"application_id"`
		AppName       string `json:"app_name"`
		Type          string `json:"type"`
		Status        string `json:"status"`
		Message       string `json:"message"`
		RejectReason  string `json:"reject_reason"`
		CreatedAt     string `json:"created_at"`
	}

	var result []RequestResponse
	for _, req := range requests {
		AdminName := ""
		if req.Admin.ID != 0 {
			AdminName = req.Admin.Username
		}

		appName := ""
		if req.Application.ID != 0 {
			appName = req.Application.Name
		}

		result = append(result, RequestResponse{
			ID:            req.ID,
			AgentID:       req.AgentID,
			AdminID:   req.AdminID,
			AdminName: AdminName,
			ApplicationID: req.ApplicationID,
			AppName:       appName,
			Type:          req.Type,
			Status:        req.Status,
			Message:       req.Message,
			RejectReason:  req.RejectReason,
			CreatedAt:     req.CreatedAt.Format("2006-01-02 15:04:05"),
		})
	}

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

func handleInviteAgent(c *gin.Context) {
	userID := c.GetUint("user_id")

	if !checkAgentPermission(userID) {
		response.Error(c, 403, "您的套餐不支持代理功能，请升级套餐")
		return
	}

	var req struct {
		AgentID       uint   `json:"agent_id"`
		ApplicationID uint   `json:"application_id"`
		Message       string `json:"message"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	var agent model.User
	if err := database.DB.First(&agent, req.AgentID).Error; err != nil {
		response.Error(c, 404, "开发者不存在")
		return
	}
	if agent.Role != "agent" {
		response.Error(c, 400, "该用户不是代理商")
		return
	}

	var app model.Application
	if err := database.DB.Where("id = ? AND user_id = ?", req.ApplicationID, userID).First(&app).Error; err != nil {
		response.Error(c, 404, "应用不存在")
		return
	}

	var existing model.AgentApplication
	if err := database.DB.Where("agent_id = ? AND application_id = ?", req.AgentID, req.ApplicationID).First(&existing).Error; err == nil {
		response.Error(c, 400, "该开发者已获得此应用的授权")
		return
	}

	request := model.AgentApplicationRequest{
		AgentID:       req.AgentID,
		AdminID:   userID,
		ApplicationID: req.ApplicationID,
		Type:          "invite",
		Status:        "pending",
		Message:       req.Message,
	}
	if err := database.DB.Create(&request).Error; err != nil {
		fmt.Printf("创建邀请错误: %v\n", err)
		response.Error(c, 500, "创建邀请失败")
		return
	}

	response.Success(c, gin.H{
		"id":         request.ID,
		"agent_id":   request.AgentID,
		"agent_name": agent.Username,
		"app_id":     request.ApplicationID,
		"app_name":   app.Name,
		"type":       request.Type,
		"status":     request.Status,
	})
}

func handleRequestAuthorization(c *gin.Context) {
	userID := c.GetUint("user_id")
	var req struct {
		AdminID   uint   `json:"admin_id"`
		ApplicationID uint   `json:"application_id"`
		Message       string `json:"message"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	var Admin model.User
	if err := database.DB.First(&Admin, req.AdminID).Error; err != nil {
		response.Error(c, 404, "开发者不存在")
		return
	}
	if Admin.Role != "admin" {
		response.Error(c, 400, "该用户不是管理员")
		return
	}

	var app model.Application
	if err := database.DB.Where("id = ? AND user_id = ?", req.ApplicationID, req.AdminID).First(&app).Error; err != nil {
		response.Error(c, 404, "应用不存在")
		return
	}

	var existing model.AgentApplication
	if err := database.DB.Where("agent_id = ? AND application_id = ?", userID, req.ApplicationID).First(&existing).Error; err == nil {
		response.Error(c, 400, "您已获得此应用的授权")
		return
	}

	var existingRequest model.AgentApplicationRequest
	if err := database.DB.Where("agent_id = ? AND admin_id = ? AND application_id = ? AND status = ?",
		userID, req.AdminID, req.ApplicationID, "pending").First(&existingRequest).Error; err == nil {
		response.Error(c, 400, "您已有待处理的申请")
		return
	}

	request := model.AgentApplicationRequest{
		AgentID:       userID,
		AdminID:   req.AdminID,
		ApplicationID: req.ApplicationID,
		Type:          "request",
		Status:        "pending",
		Message:       req.Message,
	}
	if err := database.DB.Create(&request).Error; err != nil {
		fmt.Printf("创建申请错误: %v\n", err)
		response.Error(c, 500, "创建申请失败")
		return
	}

	response.Success(c, gin.H{
		"id":             request.ID,
		"admin_id":   request.AdminID,
		"admin_name": Admin.Username,
		"app_id":         request.ApplicationID,
		"app_name":       app.Name,
		"type":           request.Type,
		"status":         request.Status,
	})
}

func handleApproveRequest(c *gin.Context) {
	userID := c.GetUint("user_id")
	requestID := c.Param("id")

	if !checkAgentPermission(userID) {
		response.Error(c, 403, "您的套餐不支持代理功能，请升级套餐")
		return
	}

	var req model.AgentApplicationRequest
	if err := database.DB.Where("id = ? AND admin_id = ?", requestID, userID).First(&req).Error; err != nil {
		response.Error(c, 404, "申请不存在")
		return
	}

	if req.Status != "pending" {
		response.Error(c, 400, "该申请已处理")
		return
	}

	tx := database.DB.Begin()

	agentApp := model.AgentApplication{
		AgentID:       req.AgentID,
		ApplicationID: req.ApplicationID,
		AdminID:   userID,
		Discount:      1.0,
		Status:        "active",
		IsReceived:    true,
	}
	if err := tx.Create(&agentApp).Error; err != nil {
		tx.Rollback()
		fmt.Printf("创建授权错误: %v\n", err)
		response.Error(c, 500, "创建授权失败")
		return
	}

	var cardTypes []model.CardType
	database.DB.Where("application_id = ? OR application_id IS NULL", req.ApplicationID).Find(&cardTypes)
	for _, ct := range cardTypes {
		agentCardType := model.AgentApplicationCardType{
			AgentApplicationID: agentApp.ID,
			CardTypeID:         ct.ID,
			CanGenerate:        false,
		}
		tx.Create(&agentCardType)
	}

	req.Status = "approved"
	if err := tx.Save(&req).Error; err != nil {
		tx.Rollback()
		response.Error(c, 500, "更新申请状态失败")
		return
	}

	tx.Commit()

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

func handleRejectRequest(c *gin.Context) {
	userID := c.GetUint("user_id")
	requestID := c.Param("id")

	var reqBody struct {
		RejectReason string `json:"reject_reason"`
	}
	if err := c.ShouldBindJSON(&reqBody); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	var req model.AgentApplicationRequest
	if err := database.DB.Where("id = ? AND admin_id = ?", requestID, userID).First(&req).Error; err != nil {
		response.Error(c, 404, "申请不存在")
		return
	}

	if req.Status != "pending" {
		response.Error(c, 400, "该申请已处理")
		return
	}

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

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

func handleGetAgentAppDetail(c *gin.Context) {
	userID := c.GetUint("user_id")
	agentAppID := c.Param("id")

	var agentApp model.AgentApplication
	if err := database.DB.Where("id = ? AND admin_id = ?", agentAppID, userID).
		Preload("CardTypes.CardType").
		First(&agentApp).Error; err != nil {
		response.Error(c, 404, "授权记录不存在")
		return
	}

	var agent model.User
	if err := database.DB.Where("id = ?", agentApp.AgentID).First(&agent).Error; err != nil {
		log.Printf("[ERROR] Failed to query agent: %v\n", err)
	}

	var application model.Application
	if err := database.DB.Where("id = ?", agentApp.ApplicationID).First(&application).Error; err != nil {
		log.Printf("[ERROR] Failed to query application: %v\n", err)
	}

	type CardTypeResponse struct {
		ID          uint    `json:"id"`
		Name        string  `json:"name"`
		Price       float64 `json:"price"`
		CanGenerate bool    `json:"can_generate"`
	}

	type AgentAppDetailResponse struct {
		ID            uint               `json:"id"`
		AgentID       uint               `json:"agent_id"`
		AgentName     string             `json:"agent_name"`
		AgentEmail    string             `json:"agent_email"`
		ApplicationID uint               `json:"application_id"`
		AppName       string             `json:"app_name"`
		Discount      float64            `json:"discount"`
		Status        string             `json:"status"`
		CardTypes     []CardTypeResponse `json:"card_types"`
		CreatedAt     string             `json:"created_at"`
	}

	var cardTypes []CardTypeResponse
	for _, ct := range agentApp.CardTypes {
		cardTypes = append(cardTypes, CardTypeResponse{
			ID:          ct.CardTypeID,
			Name:        ct.CardType.Name,
			Price:       ct.CardType.Price,
			CanGenerate: ct.CanGenerate,
		})
	}

	result := AgentAppDetailResponse{
		ID:            agentApp.ID,
		AgentID:       agentApp.AgentID,
		AgentName:     agent.Username,
		ApplicationID: agentApp.ApplicationID,
		AppName:       application.Name,
		Discount:      agentApp.Discount,
		Status:        agentApp.Status,
		CardTypes:     cardTypes,
		CreatedAt:     agentApp.CreatedAt.Format("2006-01-02 15:04:05"),
	}

	if agent.Email != nil {
		result.AgentEmail = *agent.Email
	}

	response.Success(c, result)
}

func handleUpdateAgentApp(c *gin.Context) {
	userID := c.GetUint("user_id")
	agentAppID := c.Param("id")

	var reqBody struct {
		Discount   *float64 `json:"discount"`
		Status     *string  `json:"status"`
	}
	if err := c.ShouldBindJSON(&reqBody); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	var agentApp model.AgentApplication
	if err := database.DB.Where("id = ? AND admin_id = ?", agentAppID, userID).First(&agentApp).Error; err != nil {
		response.Error(c, 404, "授权记录不存在")
		return
	}

	updates := make(map[string]interface{})
	if reqBody.Discount != nil {
		updates["discount"] = *reqBody.Discount
	}
	if reqBody.Status != nil {
		updates["status"] = *reqBody.Status
	}

	if len(updates) > 0 {
		if err := database.DB.Model(&agentApp).Updates(updates).Error; err != nil {
			response.Error(c, 500, "更新失败")
			return
		}
	}

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

func handleUpdateAgentCardTypes(c *gin.Context) {
	userID := c.GetUint("user_id")
	agentAppID := c.Param("id")

	var reqBody struct {
		CardTypes []struct {
			CardTypeID  uint `json:"card_type_id"`
			CanGenerate bool `json:"can_generate"`
		} `json:"card_types"`
	}
	if err := c.ShouldBindJSON(&reqBody); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	var agentApp model.AgentApplication
	if err := database.DB.Where("id = ? AND admin_id = ?", agentAppID, userID).First(&agentApp).Error; err != nil {
		response.Error(c, 404, "授权记录不存在")
		return
	}

	tx := database.DB.Begin()

	if err := tx.Where("agent_application_id = ?", agentAppID).Delete(&model.AgentApplicationCardType{}).Error; err != nil {
		tx.Rollback()
		response.Error(c, 500, "清除旧权限失败")
		return
	}

	for _, ct := range reqBody.CardTypes {
		agentCardType := model.AgentApplicationCardType{
			AgentApplicationID: agentApp.ID,
			CardTypeID:         ct.CardTypeID,
			CanGenerate:        ct.CanGenerate,
		}
		if err := tx.Create(&agentCardType).Error; err != nil {
			tx.Rollback()
			response.Error(c, 500, "创建权限失败")
			return
		}
	}

	tx.Commit()

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

func handleRemoveAgentApp(c *gin.Context) {
	userID := c.GetUint("user_id")
	agentAppID := c.Param("id")

	var agentApp model.AgentApplication
	if err := database.DB.Where("id = ? AND admin_id = ?", agentAppID, userID).First(&agentApp).Error; err != nil {
		response.Error(c, 404, "授权记录不存在")
		return
	}

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

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

func handleCancelRequest(c *gin.Context) {
	userID := c.GetUint("user_id")
	requestID := c.Param("id")

	var req model.AgentApplicationRequest
	if err := database.DB.Where("id = ? AND agent_id = ? AND status = ?", requestID, userID, "pending").First(&req).Error; err != nil {
		response.Error(c, 404, "申请不存在或已处理")
		return
	}

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

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