package models

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/xuri/excelize/v2"
	orm "go-admin/common/global"
	"go-admin/logger"
	"go-admin/tools"
	"go-admin/tools/config"
	"math"
	"sort"
	"strconv"
	"strings"
	"time"
)

// DailyBusinessSummary 每日经营数据汇总表
type DailyBusinessSummary struct {
	Model

	Date         time.Time `json:"date"`          // 汇总日期
	StoreID      uint      `json:"store_id"`      // 门店ID
	SalesAmount  float64   `json:"sales_amount"`  // 销售额
	PromotionFee float64   `json:"promotion_fee"` // 推广费
	SalesProfit  float64   `json:"sales_profit"`  // 销售毛利
	StaffProfit  float64   `json:"staff_profit"`  // 员工毛利
	Count        int32     `json:"count"`         // 销售数量
}

type CreateBusinessSummaryRequest struct {
	Date         string  `json:"date" binding:"required"`     // 格式：yyyy-MM-dd
	StoreID      uint    `json:"store_id" binding:"required"` // 门店id
	SalesAmount  float64 `json:"sales_amount"`                // 销售额
	PromotionFee float64 `json:"promotion_fee"`               // 推广费
	SalesProfit  float64 `json:"sales_profit"`                // 销售毛利
	StaffProfit  float64 `json:"staff_profit"`                // 员工毛利
	Count        int32   `json:"count"`                       // 销售数量
}

type BusinessSummaryListRequest struct {
	StoreId   []uint `json:"store_id"`   // 可选，复选门店ID
	StartTime string `json:"start_time"` // 开始时间
	EndTime   string `json:"end_time"`   // 结束时间
	PageIndex int    `json:"page_index"` // 当前页码
	PageSize  int    `json:"page_size"`  // 每页条数
	SortType  string `json:"sort_type"`  // 排序类型：desc 降序、asc 升序
}

type BusinessSummaryItem struct {
	Date         string  `json:"date"`          // 时间，如："2023-12-25"
	SalesAmount  float64 `json:"sales_amount"`  // 销售额
	PromotionFee float64 `json:"promotion_fee"` // 推广费
	SalesProfit  float64 `json:"sales_profit"`  // 销售毛利
	StaffProfit  float64 `json:"staff_profit"`  // 员工毛利
	Count        int32   `json:"count"`         // 销售数量
}

type BusinessSummaryListResp struct {
	List              []BusinessSummaryItem `json:"list"`
	Total             int                   `json:"total"`
	PageIndex         int                   `json:"pageIndex"`
	PageSize          int                   `json:"pageSize"`
	TotalSalesAmount  float64               `json:"total_sales_amount"`  // 总销售额
	TotalPromotionFee float64               `json:"total_promotion_fee"` // 总推广费
	TotalSalesProfit  float64               `json:"total_sales_profit"`  // 总销售毛利
	TotalStaffProfit  float64               `json:"total_staff_profit"`  // 总员工毛利
	TotalCount        int64                 `json:"total_count"`         // 总销售数量
}

// MarketStoreSalesDataReq 门店销售对比入参
type MarketStoreSalesDataReq struct {
	StoreId   []uint32 `json:"store_id"`   // 门店ID
	StartTime string   `json:"start_time"` // 开始时间
	EndTime   string   `json:"end_time"`   // 结束时间
	PageIndex int      `json:"pageIndex"`  // 页码
	PageSize  int      `json:"pageSize"`   // 页面条数
	IsExport  uint32   `json:"is_export"`  // 1-导出
	SortType  string   `json:"sort_type"`  // 排序类型：desc 降序、asc 升序
}

// MarketStoreSalesDataResp 门店销售对比出参
type MarketStoreSalesDataResp struct {
	List              []MarketStoreSalesData `json:"list"`
	Total             int                    `json:"total"`     // 总条数
	PageIndex         int                    `json:"pageIndex"` // 页码
	PageSize          int                    `json:"pageSize"`  // 每页展示条数
	ExportUrl         string                 `json:"export_url"`
	TotalSalesAmount  float64                `json:"total_sales_amount"`  // 总销售额
	TotalPromotionFee float64                `json:"total_promotion_fee"` // 总推广费
	TotalSalesProfit  float64                `json:"total_sales_profit"`  // 总销售毛利
	TotalStaffProfit  float64                `json:"total_staff_profit"`  // 总员工毛利
	TotalCount        int64                  `json:"total_count"`         // 总销售数量
}

// MarketStoreSalesData 门店销售数据
type MarketStoreSalesData struct {
	StoreId      uint32  `json:"store_id"`      // 门店id
	StoreName    string  `json:"store_name"`    // 门店名称
	SalesAmount  float64 `json:"sales_amount"`  // 销售额
	PromotionFee float64 `json:"promotion_fee"` // 推广费
	SalesProfit  float64 `json:"sales_profit"`  // 销售毛利
	StaffProfit  float64 `json:"staff_profit"`  // 员工毛利
	Count        int64   `json:"count"`         // 销售数量
}

// ParseToDate 解析多种格式的时间字符串，仅保留日期部分（年月日）
func ParseToDate(s string) (time.Time, error) {
	formats := []string{
		"2006-01-02",          // 标准日期格式
		time.RFC3339,          // 带时区时间戳 2025-05-20T00:00:00+08:00
		"2006-01-02 15:04:05", // 常见完整格式
	}

	for _, layout := range formats {
		if t, err := time.Parse(layout, s); err == nil {
			// 格式化为 YYYY-MM-DD 再转换，去除时间部分
			return time.Parse("2006-01-02", t.Format("2006-01-02"))
		}
	}

	return time.Time{}, fmt.Errorf("无法解析日期格式: %s", s)
}

func QueryListBusinessSummary(req *BusinessSummaryListRequest, c *gin.Context) (*BusinessSummaryListResp, error) {
	page := req.PageIndex - 1
	if page < 0 {
		page = 0
	}
	if req.PageSize == 0 {
		req.PageSize = 10
	}

	resp := &BusinessSummaryListResp{
		PageIndex: req.PageIndex,
		PageSize:  req.PageSize,
	}

	startDate, err1 := ParseToDate(req.StartTime)
	endDate, err2 := ParseToDate(req.EndTime)
	if err1 != nil || err2 != nil {
		return nil, errors.New("日期格式错误")
	}
	if endDate.Before(startDate) {
		return nil, errors.New("结束时间早于开始时间")
	}

	// 生成所有日期（用于补0和分页）
	var allDates []string
	for d := startDate; !d.After(endDate); d = d.AddDate(0, 0, 1) {
		allDates = append(allDates, d.Format("2006-01-02"))
	}

	// 根据排序方式进行调整
	if strings.ToLower(req.SortType) == "desc" {
		// 倒序排列
		for i, j := 0, len(allDates)-1; i < j; i, j = i+1, j-1 {
			allDates[i], allDates[j] = allDates[j], allDates[i]
		}
	}
	totalDays := len(allDates)

	// 日期分页
	start := page * req.PageSize
	end := start + req.PageSize
	if start > totalDays {
		start = totalDays
	}
	if end > totalDays {
		end = totalDays
	}
	pagedDates := allDates[start:end]

	// 查询聚合数据
	type DailyAggregatedData struct {
		Date         string  `json:"summary_date"`
		SalesAmount  float64 `json:"sales_amount"`
		PromotionFee float64 `json:"promotion_fee"`
		SalesProfit  float64 `json:"sales_profit"`
		StaffProfit  float64 `json:"staff_profit"`
		Count        int32   `json:"count"`
	}
	var dataList []DailyAggregatedData

	qs := orm.Eloquent.Table("daily_business_summary")
	es := orm.Eloquent.Table("daily_business_summary")

	if req.StartTime != "" && req.EndTime != "" {
		startTime, err := time.Parse(QueryTimeFormat, req.StartTime)
		if err != nil {
			logger.Error("startTime parse err")
		}

		endTime, err := time.Parse(QueryTimeFormat, req.EndTime)
		if err != nil {
			logger.Error("endTime parse err")
		}

		qs = qs.Where("date BETWEEN ? AND ?", startTime, endTime)
		es = es.Where("date BETWEEN ? AND ?", startTime, endTime)
	}

	// 非管理员才判断所属门店
	if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
		sysUser, err := GetSysUserByCtx(c)
		if err != nil {
			return nil, errors.New("操作失败:" + err.Error())
		}

		// 返回sysUser未过期的门店id列表
		storeList := GetValidStoreIDs(sysUser.StoreData)
		if len(storeList) > 0 {
			if len(storeList) == 1 {
				qs = qs.Where("store_id = ?", storeList[0])
				es = es.Where("store_id = ?", storeList[0])
			} else {
				qs = qs.Where("store_id IN (?)", storeList)
				es = es.Where("store_id IN (?)", storeList)
			}
		} else {
			return nil, errors.New("用户未绑定门店")
		}
	}

	if len(req.StoreId) > 0 {
		qs = qs.Where("store_id IN ?", req.StoreId)
		es = es.Where("store_id IN ?", req.StoreId)
	}

	var err error
	if req.SortType == "asc" {
		err = qs.Select("DATE_FORMAT(date, '%Y-%m-%d') AS date, " +
			"SUM(promotion_fee) AS promotion_fee, " +
			"SUM(sales_amount) AS sales_amount, " +
			"SUM(sales_profit) AS sales_profit, " +
			"SUM(staff_profit) AS staff_profit, " +
			"SUM(count) AS count").
			Group("date").
			Order("date ASC").
			Find(&dataList).Error
	} else {
		err = qs.Select("DATE_FORMAT(date, '%Y-%m-%d') AS date, " +
			"SUM(promotion_fee) AS promotion_fee, " +
			"SUM(sales_amount) AS sales_amount, " +
			"SUM(sales_profit) AS sales_profit, " +
			"SUM(staff_profit) AS staff_profit, " +
			"SUM(count) AS count").
			Group("date").
			Order("date DESC").
			Find(&dataList).Error
	}

	if err != nil {
		return nil, err
	}

	// 查询汇总数据
	var summary struct {
		TotalSalesAmount  float64
		TotalPromotionFee float64
		TotalSalesProfit  float64
		TotalStaffProfit  float64
		TotalCount        int64
	}
	err = es.Select("SUM(sales_amount) AS total_sales_amount, " +
		"SUM(promotion_fee) AS total_promotion_fee, " +
		"SUM(sales_profit) AS total_sales_profit, " +
		"SUM(staff_profit) AS total_staff_profit, " +
		"SUM(count) AS total_count").
		Find(&summary).Error
	if err != nil {
		return nil, err
	}

	// 聚合结果映射：date → 汇总值
	resultMap := make(map[string]DailyAggregatedData)
	for _, d := range dataList {
		resultMap[d.Date] = d
	}

	// 构造分页结果（补零）
	var result []BusinessSummaryItem
	for _, dateStr := range pagedDates {
		if d, ok := resultMap[dateStr]; ok {
			result = append(result, BusinessSummaryItem{
				Date:         dateStr,
				SalesAmount:  d.SalesAmount,
				PromotionFee: d.PromotionFee,
				SalesProfit:  d.SalesProfit,
				StaffProfit:  d.StaffProfit,
				Count:        d.Count,
			})
		} else {
			// 补0
			result = append(result, BusinessSummaryItem{
				Date:         dateStr,
				SalesAmount:  0,
				PromotionFee: 0,
				SalesProfit:  0,
				StaffProfit:  0,
				Count:        0,
			})
		}
	}

	switch req.SortType {
	case "asc":
		sort.Slice(result, func(i, j int) bool {
			return result[i].Date < result[j].Date
		})
	case "desc":
		sort.Slice(result, func(i, j int) bool {
			return result[i].Date > result[j].Date
		})
	}

	resp.List = result
	resp.Total = totalDays
	resp.PageIndex = req.PageIndex
	resp.PageSize = req.PageSize

	resp.TotalSalesAmount = math.Round(summary.TotalSalesAmount*100) / 100
	resp.TotalPromotionFee = math.Round(summary.TotalPromotionFee*100) / 100
	resp.TotalSalesProfit = math.Round(summary.TotalSalesProfit*100) / 100
	resp.TotalStaffProfit = math.Round(summary.TotalStaffProfit*100) / 100
	resp.TotalCount = summary.TotalCount

	return resp, nil
}

func QueryDailyBusinessSummaryData(req *MarketStoreSalesDataReq, c *gin.Context) (*MarketStoreSalesDataResp, error) {
	page := req.PageIndex - 1
	if page < 0 {
		page = 0
	}
	if req.PageSize == 0 {
		req.PageSize = 10
	}

	resp := &MarketStoreSalesDataResp{
		PageIndex: req.PageIndex,
		PageSize:  req.PageSize,
	}
	var storeManageDataList []MarketStoreSalesData

	// 查询原始数据
	qs := orm.Eloquent.Table("daily_business_summary")

	var storeList []uint32
	// 非管理员才判断所属门店
	if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
		sysUser, err := GetSysUserByCtx(c)
		if err != nil {
			return nil, errors.New("操作失败:" + err.Error())
		}

		// 返回sysUser未过期的门店id列表
		storeList = GetValidStoreIDs(sysUser.StoreData)
		if len(storeList) > 0 {
			if len(storeList) == 1 {
				qs = qs.Where("store_id = ?", storeList[0])
			} else {
				qs = qs.Where("store_id IN (?)", storeList)
			}
		} else {
			return nil, errors.New("用户未绑定门店")
		}
	} else {
		var allStoreList []Store
		err := orm.Eloquent.Table("store").Where("is_online = 1 and cooperative_business_id = 1").
			Find(&allStoreList).Error
		if err != nil {
			return nil, err
		}

		for _, v := range allStoreList {
			storeList = append(storeList, v.ID)
		}
	}

	// 限定门店
	if len(req.StoreId) > 0 {
		qs = qs.Where("store_id IN ?", req.StoreId)
	}

	// 限定时间
	if req.StartTime != "" && req.EndTime != "" {
		qs = qs.Where("date BETWEEN ? AND ?", req.StartTime, req.EndTime)
	}

	// 查询全部数据（用于聚合、分页）
	var allData []DailyBusinessSummary
	err := qs.Order("date DESC").Find(&allData).Error
	if err != nil {
		logger.Error("QueryDailyBusinessSummaryData err:", logger.Field("err", err))
		return nil, err
	}

	// 查询汇总数据
	var summary struct {
		TotalSalesAmount  float64
		TotalPromotionFee float64
		TotalSalesProfit  float64
		TotalStaffProfit  float64
		TotalCount        int64
	}
	err = qs.Select("SUM(sales_amount) AS total_sales_amount, " +
		"SUM(promotion_fee) AS total_promotion_fee, " +
		"SUM(sales_profit) AS total_sales_profit, " +
		"SUM(staff_profit) AS total_staff_profit, " +
		"SUM(count) AS total_count").
		Find(&summary).Error
	if err != nil {
		logger.Error("QueryStoreManageData summary err:", logger.Field("err", err))
		return nil, err
	}

	// 查询分页数据 按 store_id 进行汇总
	var storeData []struct {
		StoreId      uint32  `json:"store_id"`
		SalesAmount  float64 `json:"sales_amount"`
		PromotionFee float64 `json:"promotion_fee"`
		SalesProfit  float64 `json:"sales_profit"`
		StaffProfit  float64 `json:"staff_profit"`
		Count        int64   `json:"count"`
	}
	err = qs.Select("store_id, " +
		"SUM(promotion_fee) AS promotion_fee, " +
		"SUM(sales_amount) AS sales_amount, " +
		"SUM(sales_profit) AS sales_profit, " +
		"SUM(staff_profit) AS staff_profit, " +
		"SUM(count) AS count").
		Group("store_id").
		Order("store_id").
		Find(&storeData).Error
	if err != nil {
		logger.Error("QueryStoreManageData err:", logger.Field("err", err))
		return nil, err
	}

	storeMap, err := GetAllStoreData()
	if err != nil {
		return nil, err
	}

	// 组合数据
	for _, storeId := range storeList {
		flag := false
		for _, v := range storeData {
			if v.StoreId == storeId {
				flag = true
				storeManageDataList = append(storeManageDataList, MarketStoreSalesData{
					StoreId:      v.StoreId,
					StoreName:    storeMap[v.StoreId].Name,
					SalesAmount:  math.Round(v.SalesAmount*100) / 100,
					PromotionFee: math.Round(v.PromotionFee*100) / 100,
					SalesProfit:  math.Round(v.SalesProfit*100) / 100,
					StaffProfit:  math.Round(v.StaffProfit*100) / 100,
					Count:        v.Count,
				})
			} else {
				continue
			}
		}

		if !flag {
			storeManageDataList = append(storeManageDataList, MarketStoreSalesData{
				StoreId:      storeId,
				StoreName:    storeMap[storeId].Name,
				SalesAmount:  0,
				PromotionFee: 0,
				SalesProfit:  0,
				StaffProfit:  0,
				Count:        0,
			})
		}
	}

	// 汇总数据赋值给响应
	resp.TotalSalesAmount = math.Round(summary.TotalSalesAmount*100) / 100
	resp.TotalPromotionFee = math.Round(summary.TotalPromotionFee*100) / 100
	resp.TotalSalesProfit = math.Round(summary.TotalSalesProfit*100) / 100
	resp.TotalStaffProfit = math.Round(summary.TotalStaffProfit*100) / 100
	resp.TotalCount = summary.TotalCount

	// 是否导出
	if req.IsExport == 1 {
		filePath, err := marketStoreSalesDataExport(storeManageDataList, summary, c)
		if err != nil {
			logger.Error("storeSalesDataExport err:", logger.Field("err", err))
			return nil, err
		}
		resp.ExportUrl = filePath
	} else {
		// 分页
		startIndex := page * req.PageSize
		endIndex := startIndex + req.PageSize
		if endIndex > len(storeManageDataList) {
			endIndex = len(storeManageDataList)
		}
		resp.List = storeManageDataList[startIndex:endIndex]
		resp.Total = len(storeManageDataList)
	}

	return resp, nil
}

// marketStoreSalesDataExport 导出门店经营数据
func marketStoreSalesDataExport(list []MarketStoreSalesData, summary struct {
	TotalSalesAmount  float64
	TotalPromotionFee float64
	TotalSalesProfit  float64
	TotalStaffProfit  float64
	TotalCount        int64
}, c *gin.Context) (string, error) {
	file := excelize.NewFile()
	fSheet := "Sheet1"

	url := config.ExportConfig.Url
	fileName := time.Now().Format(TimeFormat) + "门店经营数据" + ".xlsx"
	fmt.Println("url fileName:", url+fileName)

	// 判断是否有入销售毛利、员工毛利的权限
	flag1, _ := checkRoleMenu(c, SalesProfitMenu)
	flag2, _ := checkRoleMenu(c, StaffProfitMenu)
	fmt.Println("flag1 is:", flag1)
	fmt.Println("flag2 is:", flag2)
	logger.Info("flag1 is:", logger.Field("flag1", flag1))
	logger.Info("flag2 is:", logger.Field("flag2", flag2))

	nEndCount := 0
	title := []interface{}{"店铺名称", "销售额", "推广费"}
	if flag1 { // 销售毛利
		title = append(title, "销售毛利")
		nEndCount += 1
	}
	if flag2 { // 员工毛利
		title = append(title, "员工毛利")
		nEndCount += 1
	}
	title = append(title, "销售数量")

	for i, _ := range title {
		cell, _ := excelize.CoordinatesToCellName(1+i, 1)
		err := file.SetCellValue(fSheet, cell, title[i])
		if err != nil {
			logger.Errorf("file set value err:", err)
		}
	}

	var row []interface{}
	nExcelStartRow := 0
	for rowId := 0; rowId < len(list); rowId++ {
		row = []interface{}{
			list[rowId].StoreName,
			list[rowId].SalesAmount,
			list[rowId].PromotionFee,
		}

		// 控制是否导出
		if flag1 { // 销售毛利
			row = append(row, list[rowId].SalesProfit)
		}
		if flag2 { // 员工毛利
			row = append(row, list[rowId].StaffProfit)
		}
		row = append(row, list[rowId].Count)

		for j, _ := range row {
			cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2)
			err := file.SetCellValue(fSheet, cell, row[j])
			if err != nil {
				logger.Error("file set value err:", logger.Field("err", err))
			}
		}
		nExcelStartRow++
	}

	totalData := "汇总 记录数:" + strconv.FormatInt(int64(len(list)), 10)
	end := []interface{}{totalData, summary.TotalSalesAmount, summary.TotalPromotionFee}

	if flag1 { // 销售毛利
		end = append(end, summary.TotalSalesProfit)
	}
	if flag2 { // 员工毛利
		end = append(end, summary.TotalStaffProfit)
	}
	end = append(end, summary.TotalCount)

	for i, _ := range end {
		cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2)
		err := file.SetCellValue(fSheet, cell, end[i])
		if err != nil {
			logger.Error("file set value err:", logger.Field("err", err))
		}
	}

	// 设置所有单元格的样式: 居中、加边框
	style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},
	"border":[{"type":"left","color":"000000","style":1},
	{"type":"top","color":"000000","style":1},
	{"type":"right","color":"000000","style":1},
	{"type":"bottom","color":"000000","style":1}]}`)

	//设置单元格高度
	file.SetRowHeight("Sheet1", 1, 20)

	// 设置单元格大小
	file.SetColWidth("Sheet1", "A", "A", 30)
	file.SetColWidth("Sheet1", "B", "B", 18)
	file.SetColWidth("Sheet1", "C", "C", 18)
	file.SetColWidth("Sheet1", "D", "D", 18)
	file.SetColWidth("Sheet1", "E", "E", 18)
	file.SetColWidth("Sheet1", "F", "F", 18)

	var endRow string
	switch nEndCount {
	case 1:
		endRow = fmt.Sprintf("E"+"%d", nExcelStartRow+2)
	case 2:
		endRow = fmt.Sprintf("F"+"%d", nExcelStartRow+2)
	default:
		endRow = fmt.Sprintf("D"+"%d", nExcelStartRow+2)
	}
	// 应用样式到整个表格
	_ = file.SetCellStyle("Sheet1", "A1", endRow, style)

	fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
	if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
		fmt.Println(err)
	}

	return url + fileName, nil
}
