package market

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	model "go-admin/app/admin/models"
	orm "go-admin/common/global"
	"go-admin/logger"
	"go-admin/tools"
	"go-admin/tools/app"
	"net/http"
	"time"
)

// ErpMarketingCouponList 优惠券列表
// @Summary 优惠券列表
// @Tags 营销管理，V1.4.4
// @Produce json
// @Accept json
// @Param request body models.ErpMarketingCouponListReq true "优惠券列表模型"
// @Success 200 {object} models.ErpMarketingCouponListResp
// @Router /api/v1/marketing/coupon/list [post]
func ErpMarketingCouponList(c *gin.Context) {
	req := &model.ErpMarketingCouponListReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error("ShouldBindJSON err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}

	resp, err := req.List()
	if err != nil {
		logger.Error("ErpMarketingCouponList err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "获取失败"+err.Error())
		return
	}

	app.OK(c, resp, "OK")
	return
}

// ErpMarketingCouponCreate 新增优惠券
// @Summary 新增优惠券
// @Tags 营销管理，V1.4.4
// @Produce json
// @Accept json
// @Param request body models.ErpMarketingCouponCreateReq true "新增优惠券模型"
// @Success 200 {object} app.Response
// @Router /api/v1/marketing/coupon/create [post]
func ErpMarketingCouponCreate(c *gin.Context) {
	var req = new(model.ErpMarketingCouponCreateReq)
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error("ShouldBindJSON err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误:"+err.Error())
		return
	}

	err := tools.Validate(req) //必填参数校验
	if err != nil {
		app.Error(c, http.StatusBadRequest, err, err.Error())
		return
	}

	if !model.IsExistingCategoryByNumber(req.CategoryNumber) {
		app.Error(c, http.StatusBadRequest, errors.New("未查询到该分类编号"), "未查询到该分类编号")
		return
	}

	err = model.CreateErpMarketingCoupon(req)
	if err != nil {
		logger.Error("CreateErpMarketingCoupon err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	app.OK(c, nil, "新增成功")
	return
}

// ErpMarketingCouponEdit 编辑优惠券
// @Summary 编辑优惠券
// @Tags 营销管理，V1.4.4
// @Produce json
// @Accept json
// @Param request body models.ErpMarketingCouponEditReq true "编辑优惠券模型"
// @Success 200 {object} app.Response
// @Router /api/v1/marketing/coupon/edit [post]
func ErpMarketingCouponEdit(c *gin.Context) {
	var req = new(model.ErpMarketingCouponEditReq)
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error("ShouldBindJSON err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误:"+err.Error())
		return
	}

	err := tools.Validate(req) //必填参数校验
	if err != nil {
		app.Error(c, http.StatusBadRequest, err, err.Error())
		return
	}

	err = model.EditErpMarketingCoupon(req)
	if err != nil {
		logger.Error("EditErpMarketingCoupon err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	app.OK(c, nil, "编辑成功")
	return
}

// ErpMarketingCouponDetail 优惠券详情
// @Summary 优惠券详情
// @Tags 营销管理，V1.4.4
// @Produce json
// @Accept json
// @Param request body models.ErpMarketingCouponDetailReq true "优惠券详情模型"
// @Success 200 {object} models.ErpCoupon
// @Router /api/v1/marketing/coupon/detail [post]
func ErpMarketingCouponDetail(c *gin.Context) {
	req := &model.ErpMarketingCouponDetailReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error("ShouldBindJSON err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}

	err := tools.Validate(req) //必填参数校验
	if err != nil {
		app.Error(c, http.StatusBadRequest, err, err.Error())
		return
	}

	// 查询订单信息
	var erpCoupon model.ErpCoupon
	err = orm.Eloquent.Table("erp_coupon").Where("id=?", req.ErpCouponId).Find(&erpCoupon).Error
	if err != nil {
		logger.Error("query erp_coupon err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	erpCoupon.Amount = erpCoupon.Amount / 100

	app.OK(c, erpCoupon, "OK")
	return
}

// ErpMarketingCouponDelete 删除优惠券
// @Summary 删除优惠券
// @Tags 营销管理，V1.4.4
// @Produce json
// @Accept json
// @Param request body models.ErpMarketingCouponDeleteReq true "删除优惠券模型"
// @Success 200 {object} app.Response
// @Router /api/v1/marketing/coupon/delete [post]
func ErpMarketingCouponDelete(c *gin.Context) {
	var req = new(model.ErpMarketingCouponDeleteReq)
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error("ShouldBindJSON err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误:"+err.Error())
		return
	}

	err := tools.Validate(req) //必填参数校验
	if err != nil {
		app.Error(c, http.StatusBadRequest, err, err.Error())
		return
	}

	err = model.DeleteErpMarketingCoupon(req)
	if err != nil {
		logger.Error("DeleteErpMarketingCoupon err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	app.OK(c, nil, "删除成功")
	return
}

// ErpMarketingCouponStart 启动优惠券发放
// @Summary 启动优惠券发放
// @Tags 营销管理，V1.4.4
// @Produce json
// @Accept json
// @Param request body models.ErpMarketingCouponStartReq true "启动优惠券发放模型"
// @Success 200 {object} app.Response
// @Router /api/v1/marketing/coupon/start [post]
func ErpMarketingCouponStart(c *gin.Context) {
	var req = new(model.ErpMarketingCouponStartReq)
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error("ShouldBindJSON err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误:"+err.Error())
		return
	}

	err := tools.Validate(req) //必填参数校验
	if err != nil {
		app.Error(c, http.StatusBadRequest, err, err.Error())
		return
	}

	// 检查是否有正在进行的任务
	taskList, err := model.GetTaskProgress(req.ErpCouponId)
	if err != nil {
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	var waitSendTaskList []model.CouponIssuanceTask

	if len(taskList) != 0 {
		for _, task := range taskList {
			switch task.Status {
			case model.TaskInProgress: // 执行中
				app.Error(c, http.StatusInternalServerError, errors.New(fmt.Sprintf("[%s]已在执行中，请勿重复启动", task.ErpCouponName)),
					fmt.Sprintf("[%s]已在执行中，请勿重复启动", task.ErpCouponName))
				return
			case model.TaskCompleted: // 已完成
				app.Error(c, http.StatusInternalServerError, errors.New(fmt.Sprintf("[%s]已执行完成", task.ErpCouponName)),
					fmt.Sprintf("[%s]已执行完成", task.ErpCouponName))
				return
			default:
				waitSendTaskList = append(waitSendTaskList, task)
			}
		}
	}

	// 校验批量选择的优惠券使用人群是否相同
	if !model.CheckUserType(req.ErpCouponId) {
		app.Error(c, http.StatusInternalServerError, errors.New("优惠券适用人群不同，不能同时启动"), "优惠券适用人群不同，不能同时启动")
	}

	// 更新短信和备注
	err = orm.Eloquent.Table("erp_coupon").Where("id in ?", req.ErpCouponId).
		Updates(map[string]interface{}{
			"remark":      req.Remark,
			"state":       model.ErpCouponSending,
			"start_time":  time.Now(),
			"sms_content": req.SmsContent,
			"updated_at":  time.Now(),
		}).Error
	if err != nil {
		logger.Errorf("更新任务完成状态失败: %v", err)
		app.Error(c, http.StatusInternalServerError, err, err.Error())
	}

	go model.StartCouponIssuanceTask(req, waitSendTaskList)

	app.OK(c, nil, "启动成功")
	return
}

// ErpMarketingCouponData 优惠券数据
// @Summary 优惠券数据
// @Tags 营销管理，V1.4.4
// @Produce json
// @Accept json
// @Param request body models.ErpMarketingCouponDataReq true "优惠券数据模型"
// @Success 200 {object}  models.ErpMarketingCouponDataResp
// @Router /api/v1/marketing/coupon/data [post]
func ErpMarketingCouponData(c *gin.Context) {
	var req model.ErpMarketingCouponDataReq
	if err := c.ShouldBindJSON(&req); err != nil {
		app.Error(c, http.StatusBadRequest, err, "参数错误:"+err.Error())
		return
	}

	userCouponIds, err := model.GetUserCouponIdsByErpCouponId(req.ErpCouponId)
	if err != nil {
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	// 查询使用该优惠券的订单商品
	var orderCommodities []model.ErpOrderCommodity
	err = orm.Eloquent.Where("coupon_id in ?", userCouponIds).
		Joins("JOIN erp_order ON erp_order.id = erp_order_commodity.erp_order_id").
		Where("erp_order.state = 'audited'").Find(&orderCommodities).Error
	if err != nil {
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	// 初始化统计数据
	var totalAmount, totalDiscount float64
	var orderCount, customerCount, productCount int
	productsMap := make(map[uint32]model.ProductInfo)
	customers := make(map[int]bool) // 用来去重客户

	// 统计订单数据
	for _, orderCommodity := range orderCommodities {
		// 获取订单详情
		var order model.ErpOrder
		err = orm.Eloquent.First(&order, orderCommodity.ErpOrderId).Error
		if err != nil {
			app.Error(c, http.StatusInternalServerError, err, err.Error())
			return
		}

		// 计算用券总成交额和总优惠金额
		totalAmount += orderCommodity.ReceivedAmount
		totalDiscount += orderCommodity.CouponDiscount

		// 计算订单数
		orderCount++

		// 计算客户数
		if _, exists := customers[order.Uid]; !exists {
			customers[order.Uid] = true
			customerCount++
		}

		// 计算购买商品总件数
		productCount += int(orderCommodity.Count)
		if _, exists := productsMap[orderCommodity.ErpCommodityId]; !exists {
			productsMap[orderCommodity.ErpCommodityId] = model.ProductInfo{
				ProductID:   int(orderCommodity.ErpCommodityId),
				ProductName: orderCommodity.ErpCommodityName,
				PayCount:    int(orderCommodity.Count),
				PayCustomer: 1,
			}
		} else {
			productInfo := productsMap[orderCommodity.ErpCommodityId]
			productInfo.PayCount += int(orderCommodity.Count)
			productInfo.PayCustomer++
			productsMap[orderCommodity.ErpCommodityId] = productInfo
		}
	}

	// 计算费效比
	var costEffectiveness float64
	if totalAmount > 0 {
		costEffectiveness = tools.RoundFloat(totalDiscount / totalAmount)
	}

	// 计算用券笔单价
	var unitPrice float64
	if orderCount > 0 {
		unitPrice = tools.RoundFloat(totalAmount / float64(orderCount))
	}

	// 构造返回的数据结构
	resp := model.ErpMarketingCouponDataResp{
		TotalAmount:       totalAmount,
		TotalDiscount:     totalDiscount,
		CostEffectiveness: costEffectiveness,
		OrderCount:        orderCount,
		UnitPrice:         unitPrice,
		CustomerCount:     customerCount,
		ProductCount:      productCount,
	}

	// 转换商品数据
	for _, productInfo := range productsMap {
		resp.Products = append(resp.Products, productInfo)
	}

	// 返回结果
	app.OK(c, resp, "OK")
}

// GenerateScheme 获取小程序跳转链接
// @Summary 获取小程序跳转链接
// @Tags 营销管理，V1.4.4
// @Produce json
// @Accept json
// @Param request body models.GenerateSchemeReq true "获取小程序跳转链接模型"
// @Success 200 {object}  models.GenerateSchemeResp
// @Router /api/v1/marketing/generateScheme [post]
func GenerateScheme(c *gin.Context) {
	var req model.GenerateSchemeReq
	if err := c.ShouldBindJSON(&req); err != nil {
		app.Error(c, http.StatusBadRequest, err, "参数错误:"+err.Error())
		return
	}

	err := tools.Validate(req) //必填参数校验
	if err != nil {
		app.Error(c, http.StatusBadRequest, err, err.Error())
		return
	}

	resp, err := model.WXGenerateScheme(&req)
	if err != nil {
		logger.Error("WXGenerateScheme err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	// 返回结果
	app.OK(c, resp, "OK")
}
