package service

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/xuri/excelize/v2"
	"strconv"
	"youngee_b_api/app/dao"
	"youngee_b_api/app/entity"
	"youngee_b_api/app/vo"
)

type TaskInfoService struct{}

// 带货待发货、待签收、已签收统计
func (t TaskInfoService) LogisticsSelectionTalentCount(param *vo.LogisticsSelectionTalentParam) map[string]int64 {
	res := make(map[string]int64)
	var needDelivery int64
	var needReceive int64
	var received int64
	dao.Db.Model(&entity.SelectionTaskInfo{}).Where("selection_id = ? AND free_stage = ?", param.SelectionId, 3).Count(&needDelivery)
	dao.Db.Model(&entity.SelectionTaskInfo{}).Where("selection_id = ? AND free_stage = ?", param.SelectionId, 4).Count(&needReceive)
	dao.Db.Model(&entity.SelectionTaskInfo{}).Where("selection_id = ? AND free_stage = ?", param.SelectionId, 5).Count(&received)
	res["needDelivery"] = needDelivery
	res["needReceive"] = needReceive
	res["received"] = received

	return res
}

// 达人物流管理
func (t TaskInfoService) LogisticsTalentList(param *vo.LogisticsTalentParam) (*vo.ResultVO, error) {
	if param.Page <= 0 {
		param.Page = 1
	}
	if param.PageSize <= 0 {
		param.PageSize = 10
	}
	var reLogisticsTalents []*vo.ReLogisticsTalent
	var total int64
	result := vo.ResultVO{
		Page:     param.Page,
		PageSize: param.PageSize,
		Total:    total,
		Data:     reLogisticsTalents,
	}
	var projectTaskInfos []*entity.ProjectTaskInfo
	var err error
	projectId := param.ProjectId
	if param.Status == 1 { // 待发货
		projectTaskInfos, total, err = dao.ProjectTaskInfoDao{}.GetListByTaskStage(projectId, 4, "", param.Page, param.PageSize, param.Nickname)
	} else if param.Status == 2 { // 待签收
		projectTaskInfos, total, err = dao.ProjectTaskInfoDao{}.GetListByTaskStage(projectId, 5, param.DeliveryTime, param.Page, param.PageSize, param.Nickname)
	} else if param.Status == 3 { // 已签收
		projectTaskInfos, total, err = dao.ProjectTaskInfoDao{}.GetListByTaskStage(projectId, 6, "", param.Page, param.PageSize, param.Nickname)
	}
	if err != nil {
		return nil, err
	}
	for _, projectTaskInfo := range projectTaskInfos {
		// 获取达人信息
		talentInfo, err := dao.TalentInfoDao{}.SelectTalentInfo(projectTaskInfo.TalentID)
		if err != nil {
			return nil, err
		}
		regionName, err := dao.RegionInfoDao{}.SelectRegion(talentInfo.VisitStoreRegion)
		if err != nil {
			regionName = ""
		}
		taskLogistics, err := dao.TaskLogisticsDao{}.SelectTaskLogistics(projectTaskInfo.TaskID)
		if err != nil {
			return nil, err
		}
		talentPreview := &vo.TalentPreview{
			TalentId:    projectTaskInfo.TalentID,
			TalentPhoto: talentInfo.Avatar,
			TalentName:  talentInfo.TalentWxNickname,
			Account:     "",
			Location:    regionName,
			Gender:      talentInfo.Sex,
		}
		reLogisticsTalent := &vo.ReLogisticsTalent{
			TalentPostAddrSnap: projectTaskInfo.TalentPostAddrSnap,
			ReTalentPreview:    talentPreview,
			LogisticsId:        taskLogistics.LogisticsID,
			CompanyName:        taskLogistics.CompanyName,
			LogisticsNumber:    taskLogistics.LogisticsNumber,
			Operator:           "",
			//DeliveryTime:       taskLogistics.DeliveryTime.Format("2006-01-02 15:04:05"),
			//SignedTime:         taskLogistics.SignedTime.Format("2006-01-02 15:04:05"),
		}
		if param.Status == 2 {
			reLogisticsTalent.DeliveryTime = projectTaskInfo.DeliveryDate.Format("2006-01-02 15:04:05")
		}
		if param.Status == 3 {
			reLogisticsTalent.SignedTime = projectTaskInfo.SignedTime.Format("2006-01-02 15:04:05")
		}
		reLogisticsTalents = append(reLogisticsTalents, reLogisticsTalent)
	}
	result = vo.ResultVO{
		Page:     param.Page,
		PageSize: param.PageSize,
		Total:    total,
		Data:     reLogisticsTalents,
	}
	return &result, nil
}

// 导出种草达人物流数据
func (t TaskInfoService) LogisticsExport(param *vo.LogisticsTalentParam) (*excelize.File, error) {
	// 准备数据
	var logisticsExports []*vo.LogisticsExport
	param.Page = 1
	param.PageSize = 1<<31 - 1
	var projectTaskInfos []*entity.ProjectTaskInfo
	var err error
	projectId := param.ProjectId
	if param.Status == 1 { // 待发货
		projectTaskInfos, _, err = dao.ProjectTaskInfoDao{}.GetListByTaskStage(projectId, 4, "", param.Page, param.PageSize, param.Nickname)
	} else if param.Status == 2 { // 待签收
		projectTaskInfos, _, err = dao.ProjectTaskInfoDao{}.GetListByTaskStage(projectId, 5, param.DeliveryTime, param.Page, param.PageSize, param.Nickname)
	} else if param.Status == 3 { // 已签收
		projectTaskInfos, _, err = dao.ProjectTaskInfoDao{}.GetListByTaskStage(projectId, 6, "", param.Page, param.PageSize, param.Nickname)
	}
	if err != nil {
		return nil, err
	}
	for _, projectTaskInfo := range projectTaskInfos {
		var talentDeliveryAddress entity.TalentDeliveryAddress
		err = json.Unmarshal([]byte(projectTaskInfo.TalentPostAddrSnap), &talentDeliveryAddress)
		if err != nil {
			fmt.Println("解析 JSON 失败:", err)
			return nil, err
		}
		taskLogistics, err := dao.TaskLogisticsDao{}.SelectTaskLogistics(projectTaskInfo.TaskID)
		if err != nil {
			return nil, err
		}
		logisticsExport := &vo.LogisticsExport{
			TalentId:        projectTaskInfo.TalentID,
			TalentName:      projectTaskInfo.TalentName,
			ReceiverName:    talentDeliveryAddress.ReceiverName,
			PhoneNumber:     talentDeliveryAddress.PhoneNumber,
			Province:        strconv.Itoa(talentDeliveryAddress.RegionCode),
			City:            strconv.Itoa(talentDeliveryAddress.RegionCode),
			County:          strconv.Itoa(talentDeliveryAddress.RegionCode),
			DetailAddr:      talentDeliveryAddress.DetailAddr,
			CompanyName:     taskLogistics.CompanyName,
			LogisticsNumber: taskLogistics.LogisticsNumber,
			Operator:        "",
		}
		if param.Status == 2 {
			logisticsExport.Time = projectTaskInfo.DeliveryDate.Format("2006-01-02 15:04:05")
		}
		if param.Status == 3 {
			logisticsExport.Time = projectTaskInfo.SignedTime.Format("2006-01-02 15:04:05")
		}
		logisticsExports = append(logisticsExports, logisticsExport)
	}
	// 打开 Excel 模板
	templatePath := "export_template.xlsx"
	f, err10 := excelize.OpenFile(templatePath)
	if err10 != nil {
		return nil, errors.New(fmt.Sprintf("加载模板失败: %s", err10))
	}
	// 写入数据
	sheet := "Sheet1"
	startRow := 2
	for i, logisticsExport := range logisticsExports {
		row := strconv.Itoa(startRow + i)
		_ = f.SetCellValue(sheet, "A"+row, logisticsExport.TalentId)
		_ = f.SetCellValue(sheet, "B"+row, logisticsExport.TalentName)
		_ = f.SetCellValue(sheet, "C"+row, logisticsExport.ReceiverName)
		_ = f.SetCellValue(sheet, "D"+row, logisticsExport.PhoneNumber)
		_ = f.SetCellValue(sheet, "E"+row, logisticsExport.Province)
		_ = f.SetCellValue(sheet, "F"+row, logisticsExport.City)
		_ = f.SetCellValue(sheet, "G"+row, logisticsExport.County)
		_ = f.SetCellValue(sheet, "H"+row, logisticsExport.DetailAddr)
		_ = f.SetCellValue(sheet, "I"+row, logisticsExport.CompanyName)
		_ = f.SetCellValue(sheet, "J"+row, logisticsExport.LogisticsNumber)
		_ = f.SetCellValue(sheet, "K"+row, logisticsExport.Operator)
		_ = f.SetCellValue(sheet, "L"+row, logisticsExport.Time)
	}

	return f, nil
}

// 种草待发货、待签收、已签收统计
func (t TaskInfoService) LogisticsTalentCount(param *vo.LogisticsTalentParam) map[string]int64 {
	res := make(map[string]int64)
	var needDelivery int64
	var needReceive int64
	var received int64
	dao.Db.Model(&entity.ProjectTaskInfo{}).Where("project_id = ? AND task_stage = ?", param.ProjectId, 4).Count(&needDelivery)
	dao.Db.Model(&entity.ProjectTaskInfo{}).Where("project_id = ? AND task_stage = ?", param.ProjectId, 5).Count(&needReceive)
	dao.Db.Model(&entity.ProjectTaskInfo{}).Where("project_id = ? AND task_stage = ?", param.ProjectId, 6).Count(&received)
	res["needDelivery"] = needDelivery
	res["needReceive"] = needReceive
	res["received"] = received

	return res
}

func (t TaskInfoService) SelectionRewardCashDetail(param *vo.SelectionRewardCashParam) (*vo.ReSelectionRewardCash, error) {
	if param.Page == 0 {
		param.Page = 1
	}
	if param.PageSize == 0 {
		param.PageSize = 10
	}
	selectionInfo, err := dao.SelectionInfoDAO{}.GetSelectionInfoById(param.SelectionId)
	if err != nil {
		return nil, err
	}
	rewardPoolAmount := selectionInfo.EstimatedCost
	rewardPoolCashed := selectionInfo.TaskReward
	selectionTaskInfos, total, err1 := dao.SelectionTaskInfoDao{}.GetRewardDetailByRewardStage(param.SelectionId, 2, param.Order, param.Page, param.PageSize)
	if err1 != nil {
		return nil, err1
	}
	var talentRewardMsgs []vo.TalentRewardMsg
	for _, selectionTaskInfo := range selectionTaskInfos {
		talentInfo, _ := dao.TalentInfoDao{}.SelectTalentInfo(selectionTaskInfo.TalentID)
		talentRewardMsg := vo.TalentRewardMsg{
			PhotoUrl: talentInfo.Avatar,
			Nickname: talentInfo.TalentNickname,
			Account:  talentInfo.TalentWxOpenid,
			Gender:   talentInfo.Sex,
			OrderNum: selectionTaskInfo.SaleActual,
			CashTime: selectionTaskInfo.WithdrawDate.Format("2006-01-02 15:04:05"),
		}
		talentRewardMsgs = append(talentRewardMsgs, talentRewardMsg)
	}
	talentMsgList := vo.ResultVO{
		Page:     param.Page,
		PageSize: param.PageSize,
		Total:    total,
		Data:     talentRewardMsgs,
	}
	reSelectionRewardCash := &vo.ReSelectionRewardCash{
		RewardPoolAmount: rewardPoolAmount,
		RewardPoolCashed: rewardPoolCashed,
		CashedRate:       rewardPoolCashed / rewardPoolAmount,
		TalentNum:        total,
		TalentMsgList:    talentMsgList,
	}

	return reSelectionRewardCash, nil
}
