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"
)

type FinanceRecordResponse struct {
	ID          uint    `json:"id"`
	OrderNo     string  `json:"order_no"`
	Type        string  `json:"type"`
	UserID      uint    `json:"user_id"`
	AppID       uint    `json:"app_id"`
	Amount      float64 `json:"amount"`
	Detail      string  `json:"detail"`
	Status      string  `json:"status"`
	PaymentType string  `json:"payment_type"`
	Remark      string  `json:"remark"`
	CreatedAt   string  `json:"created_at"`
	User        *struct {
		ID       uint   `json:"id"`
		Username string `json:"username"`
		Email    string `json:"email"`
	} `json:"user,omitempty"`
}

func SetupFinanceRoutes(r *gin.RouterGroup) {
	finance := r.Group("/finance")
	{
		finance.GET("/stats", handleGetFinanceStatistics)
		finance.GET("/statistics", handleGetFinanceStatistics)
		finance.GET("/recharge-records", handleGetRechargeRecords)
		finance.GET("/consumption-records", handleGetConsumptionRecords)
		finance.GET("/records", handleGetFinanceRecords)
		finance.DELETE("/records/:id", handleDeleteFinanceRecord)
		finance.POST("/records/batch-delete", handleBatchDeleteFinanceRecords)
	}
}

func handleGetFinanceStatistics(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, 401, "未授权")
		return
	}

	var appIDs []uint
	database.DB.Model(&model.Application{}).Where("user_id = ?", userID).Pluck("id", &appIDs)

	if len(appIDs) == 0 {
		response.Success(c, gin.H{
			"total_income":         0,
			"total_expense":        0,
			"net_profit":           0,
			"monthly_transactions": 0,
		})
		return
	}

	var appUserIDs []uint
	database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Pluck("id", &appUserIDs)

	if len(appUserIDs) == 0 {
		response.Success(c, gin.H{
			"total_income":         0,
			"total_expense":        0,
			"net_profit":           0,
			"monthly_transactions": 0,
		})
		return
	}

	var totalIncome float64
	var totalExpense float64

	database.DB.Model(&model.RechargeRecord{}).
		Where("user_id IN ? AND status = ?", appUserIDs, "success").
		Select("COALESCE(SUM(amount), 0)").
		Scan(&totalIncome)

	database.DB.Model(&model.ConsumptionRecord{}).
		Where("user_id IN ? AND status = ?", appUserIDs, "success").
		Select("COALESCE(SUM(amount), 0)").
		Scan(&totalExpense)

	response.Success(c, gin.H{
		"total_income":  totalIncome,
		"total_expense": totalExpense,
		"net_profit":    totalIncome - totalExpense,
	})
}

func handleGetRechargeRecords(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, 401, "未授权")
		return
	}

	var appIDs []uint
	database.DB.Model(&model.Application{}).Where("user_id = ?", userID).Pluck("id", &appIDs)

	if len(appIDs) == 0 {
		response.Success(c, gin.H{
			"records": []model.RechargeRecord{},
			"total":   0,
		})
		return
	}

	var appUserIDs []uint
	database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Pluck("id", &appUserIDs)

	if len(appUserIDs) == 0 {
		response.Success(c, gin.H{
			"records": []model.RechargeRecord{},
			"total":   0,
		})
		return
	}

	var records []model.RechargeRecord
	query := database.DB.Model(&model.RechargeRecord{}).Preload("AppUser").Where("user_id IN ?", appUserIDs)

	search := c.Query("search")
	status := c.Query("status")
	startDate := c.Query("start_date")
	endDate := c.Query("end_date")

	if search != "" {
		query = query.Where("order_no LIKE ? OR card_code LIKE ?", "%"+search+"%", "%"+search+"%")
	}
	if status != "" && status != "all" {
		query = query.Where("status = ?", status)
	}
	if startDate != "" {
		query = query.Where("created_at >= ?", startDate)
	}
	if endDate != "" {
		query = query.Where("created_at <= ?", endDate+" 23:59:59")
	}

	if err := query.Order("created_at DESC").Find(&records).Error; err != nil {
		response.Error(c, 500, "获取充值记录失败")
		return
	}
	response.Success(c, gin.H{
		"records": records,
		"total":   len(records),
	})
}

func handleGetConsumptionRecords(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, 401, "未授权")
		return
	}

	var appIDs []uint
	database.DB.Model(&model.Application{}).Where("user_id = ?", userID).Pluck("id", &appIDs)

	if len(appIDs) == 0 {
		response.Success(c, gin.H{
			"records": []model.ConsumptionRecord{},
			"total":   0,
		})
		return
	}

	var appUserIDs []uint
	database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Pluck("id", &appUserIDs)

	if len(appUserIDs) == 0 {
		response.Success(c, gin.H{
			"records": []model.ConsumptionRecord{},
			"total":   0,
		})
		return
	}

	var records []model.ConsumptionRecord
	query := database.DB.Model(&model.ConsumptionRecord{}).Preload("AppUser").Where("user_id IN ?", appUserIDs)

	search := c.Query("search")
	recordType := c.Query("type")
	status := c.Query("status")
	startDate := c.Query("start_date")
	endDate := c.Query("end_date")

	if search != "" {
		query = query.Where("order_no LIKE ? OR content LIKE ?", "%"+search+"%", "%"+search+"%")
	}
	if recordType != "" && recordType != "all" {
		query = query.Where("type = ?", recordType)
	}
	if status != "" && status != "all" {
		query = query.Where("status = ?", status)
	}
	if startDate != "" {
		query = query.Where("created_at >= ?", startDate)
	}
	if endDate != "" {
		query = query.Where("created_at <= ?", endDate+" 23:59:59")
	}

	if err := query.Order("created_at DESC").Find(&records).Error; err != nil {
		response.Error(c, 500, "获取消费记录失败")
		return
	}
	response.Success(c, gin.H{
		"records": records,
		"total":   len(records),
	})
}

func handleGetFinanceRecords(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, 401, "未授权")
		return
	}

	var appIDs []uint
	database.DB.Model(&model.Application{}).Where("user_id = ?", userID).Pluck("id", &appIDs)

	if len(appIDs) == 0 {
		response.Success(c, gin.H{
			"recharge_records":    []FinanceRecordResponse{},
			"consumption_records": []FinanceRecordResponse{},
			"total":               0,
		})
		return
	}

	var appUserIDs []uint
	database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Pluck("id", &appUserIDs)

	if len(appUserIDs) == 0 {
		response.Success(c, gin.H{
			"recharge_records":    []FinanceRecordResponse{},
			"consumption_records": []FinanceRecordResponse{},
			"total":               0,
		})
		return
	}

	page := c.DefaultQuery("page", "1")
	pageSize := c.DefaultQuery("page_size", "10")
	search := c.Query("search")
	recordType := c.Query("type")
	status := c.Query("status")
	startDate := c.Query("start_date")
	endDate := c.Query("end_date")

	var rechargeRecords []model.RechargeRecord
	rechargeQuery := database.DB.Model(&model.RechargeRecord{}).Preload("AppUser").Where("user_id IN ?", appUserIDs)

	if search != "" {
		rechargeQuery = rechargeQuery.Where("order_no LIKE ? OR card_code LIKE ?", "%"+search+"%", "%"+search+"%")
	}
	if recordType == "recharge" || recordType == "" || recordType == "all" {
		if status != "" && status != "all" {
			rechargeQuery = rechargeQuery.Where("status = ?", status)
		}
		if startDate != "" {
			rechargeQuery = rechargeQuery.Where("created_at >= ?", startDate)
		}
		if endDate != "" {
			rechargeQuery = rechargeQuery.Where("created_at <= ?", endDate+" 23:59:59")
		}
		if err := rechargeQuery.Order("created_at DESC").Find(&rechargeRecords).Error; err != nil {
			response.Error(c, 500, "获取充值记录失败")
			return
		}
	}

	var consumptionRecords []model.ConsumptionRecord
	consumptionQuery := database.DB.Model(&model.ConsumptionRecord{}).Preload("AppUser").Where("user_id IN ?", appUserIDs)

	if search != "" {
		consumptionQuery = consumptionQuery.Where("order_no LIKE ? OR content LIKE ?", "%"+search+"%", "%"+search+"%")
	}
	if recordType == "consumption" || recordType == "" || recordType == "all" {
		if status != "" && status != "all" {
			consumptionQuery = consumptionQuery.Where("status = ?", status)
		}
		if startDate != "" {
			consumptionQuery = consumptionQuery.Where("created_at >= ?", startDate)
		}
		if endDate != "" {
			consumptionQuery = consumptionQuery.Where("created_at <= ?", endDate+" 23:59:59")
		}
		if err := consumptionQuery.Order("created_at DESC").Find(&consumptionRecords).Error; err != nil {
			response.Error(c, 500, "获取消费记录失败")
			return
		}
	}

	var allRecords []FinanceRecordResponse
	for _, r := range rechargeRecords {
		var user *struct {
			ID       uint   `json:"id"`
			Username string `json:"username"`
			Email    string `json:"email"`
		}
		if r.AppUser != nil && r.AppUser.ID != 0 {
			user = &struct {
				ID       uint   `json:"id"`
				Username string `json:"username"`
				Email    string `json:"email"`
			}{
				ID:       r.AppUser.ID,
				Username: r.AppUser.Username,
				Email:    r.AppUser.Email,
			}
		}
		allRecords = append(allRecords, FinanceRecordResponse{
			ID:          r.ID,
			OrderNo:     r.OrderNo,
			Type:        "recharge",
			UserID:      r.UserID,
			AppID:       r.AppUser.ApplicationID,
			Amount:      r.Amount,
			Detail:      r.CardCode,
			Status:      r.Status,
			PaymentType: r.PaymentType,
			Remark:      r.Remark,
			CreatedAt:   r.CreatedAt.Format("2006-01-02 15:04:05"),
			User:        user,
		})
	}

	for _, r := range consumptionRecords {
		var user *struct {
			ID       uint   `json:"id"`
			Username string `json:"username"`
			Email    string `json:"email"`
		}
		if r.AppUser != nil && r.AppUser.ID != 0 {
			user = &struct {
				ID       uint   `json:"id"`
				Username string `json:"username"`
				Email    string `json:"email"`
			}{
				ID:       r.AppUser.ID,
				Username: r.AppUser.Username,
				Email:    r.AppUser.Email,
			}
		}
		allRecords = append(allRecords, FinanceRecordResponse{
			ID:          r.ID,
			OrderNo:     r.OrderNo,
			Type:        "consumption",
			UserID:      r.UserID,
			AppID:       r.AppUser.ApplicationID,
			Amount:      r.Amount,
			Detail:      r.Content,
			Status:      r.Status,
			PaymentType: r.PaymentType,
			Remark:      r.Remark,
			CreatedAt:   r.CreatedAt.Format("2006-01-02 15:04:05"),
			User:        user,
		})
	}

	total := len(allRecords)
	start := 0
	end := total
	if p, err := parseInt(page); err == nil && p > 0 {
		if ps, err := parseInt(pageSize); err == nil && ps > 0 {
			start = (p - 1) * ps
			end = start + ps
			if start > total {
				start = total
			}
			if end > total {
				end = total
			}
		}
	}

	if start > end {
		start = end
	}

	response.Success(c, gin.H{
		"records": allRecords[start:end],
		"total":   total,
	})
}

func parseInt(s string) (int, error) {
	var result int
	_, err := fmt.Sscanf(s, "%d", &result)
	return result, err
}

func handleDeleteFinanceRecord(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, 401, "未授权")
		return
	}

	recordID := c.Param("id")
	recordType := c.Query("type")

	var appIDs []uint
	database.DB.Model(&model.Application{}).Where("user_id = ?", userID).Pluck("id", &appIDs)
	if len(appIDs) == 0 {
		response.Error(c, 404, "记录不存在")
		return
	}

	var appUserIDs []uint
	database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Pluck("id", &appUserIDs)
	if len(appUserIDs) == 0 {
		response.Error(c, 404, "记录不存在")
		return
	}

	var deletedType string
	var deletedAmount float64

	if recordType == "recharge" {
		var record model.RechargeRecord
		if err := database.DB.Where("id = ? AND user_id IN ?", recordID, appUserIDs).First(&record).Error; err != nil {
			response.Error(c, 404, "记录不存在")
			return
		}
		if err := database.DB.Delete(&record).Error; err != nil {
			response.Error(c, 500, "删除失败")
			return
		}
		deletedType = "充值记录"
		deletedAmount = record.Amount
	} else if recordType == "consumption" {
		var record model.ConsumptionRecord
		if err := database.DB.Where("id = ? AND user_id IN ?", recordID, appUserIDs).First(&record).Error; err != nil {
			response.Error(c, 404, "记录不存在")
			return
		}
		if err := database.DB.Delete(&record).Error; err != nil {
			response.Error(c, 500, "删除失败")
			return
		}
		deletedType = "消费记录"
		deletedAmount = record.Amount
	} else {
		var rechargeRecord model.RechargeRecord
		var consumptionRecord model.ConsumptionRecord

		if err := database.DB.Where("id = ? AND user_id IN ?", recordID, appUserIDs).First(&rechargeRecord).Error; err == nil {
			database.DB.Delete(&rechargeRecord)
			deletedType = "充值记录"
			deletedAmount = rechargeRecord.Amount
			service.LogOperation(c, "delete", "finance_record", nil, fmt.Sprintf("删除%s: %.2f", deletedType, deletedAmount), nil)
			response.Success(c, nil)
			return
		}

		if err := database.DB.Where("id = ? AND user_id IN ?", recordID, appUserIDs).First(&consumptionRecord).Error; err == nil {
			database.DB.Delete(&consumptionRecord)
			deletedType = "消费记录"
			deletedAmount = consumptionRecord.Amount
			service.LogOperation(c, "delete", "finance_record", nil, fmt.Sprintf("删除%s: %.2f", deletedType, deletedAmount), nil)
			response.Success(c, nil)
			return
		}

		response.Error(c, 404, "记录不存在")
		return
	}

	service.LogOperation(c, "delete", "finance_record", nil, fmt.Sprintf("删除%s: %.2f", deletedType, deletedAmount), nil)

	response.Success(c, nil)
}

func handleBatchDeleteFinanceRecords(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		response.Error(c, 401, "未授权")
		return
	}

	var req struct {
		IDs []uint `json:"ids"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

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

	var appIDs []uint
	database.DB.Model(&model.Application{}).Where("user_id = ?", userID).Pluck("id", &appIDs)
	if len(appIDs) == 0 {
		response.Error(c, 404, "记录不存在")
		return
	}

	var appUserIDs []uint
	database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Pluck("id", &appUserIDs)
	if len(appUserIDs) == 0 {
		response.Error(c, 404, "记录不存在")
		return
	}

	database.DB.Where("id IN ? AND user_id IN ?", req.IDs, appUserIDs).Delete(&model.RechargeRecord{})
	database.DB.Where("id IN ? AND user_id IN ?", req.IDs, appUserIDs).Delete(&model.ConsumptionRecord{})

	service.LogOperation(c, "batch_delete", "finance_record", nil, fmt.Sprintf("批量删除财务记录: %d条", len(req.IDs)), nil)

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