package camel_oil

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/xuri/excelize/v2"

	"github.com/gogf/gf/v2/os/gtime"
	v1 "kami/api/camel_oil/v1"
	"kami/internal/consts"
	"kami/internal/dao"
	"kami/internal/model/entity"
	"kami/utility/config"
)

// ====================================================================================
// 订单查询相关方法
// ====================================================================================

// ListOrder 查询订单列表
func (s *sCamelOil) ListOrder(ctx context.Context, req *v1.ListOrderReq) (res *v1.ListOrderRes, err error) {
	m := dao.V1CamelOilOrder.Ctx(ctx).DB(config.GetDatabaseV1())

	// 构建查询条件
	if req.MerchantOrderId != "" {
		m = m.Where(dao.V1CamelOilOrder.Columns().MerchantOrderId, req.MerchantOrderId)
	}
	if req.OrderNo != "" {
		m = m.Where(dao.V1CamelOilOrder.Columns().OrderNo, req.OrderNo)
	}
	if req.AccountId != 0 {
		m = m.Where(dao.V1CamelOilOrder.Columns().AccountId, req.AccountId)
	}
	if req.Status > 0 {
		m = m.Where(dao.V1CamelOilOrder.Columns().Status, int(req.Status))
	}
	if req.PayStatus > 0 {
		m = m.Where(dao.V1CamelOilOrder.Columns().PayStatus, int(req.PayStatus))
	}
	if len(req.DateRange) == 2 && req.DateRange[0] != nil && req.DateRange[1] != nil {
		m = m.WhereBetween(dao.V1CamelOilOrder.Columns().CreatedAt, req.DateRange[0], req.DateRange[1])
	}

	// 查询总数
	total, err := m.Count()
	if err != nil {
		return nil, gerror.Wrap(err, "查询订单总数失败")
	}

	// 分页查询
	var orders []*entity.V1CamelOilOrder
	err = m.Page(req.Current, req.PageSize).
		OrderDesc(dao.V1CamelOilOrder.Columns().CreatedAt).
		Scan(&orders)
	if err != nil {
		return nil, gerror.Wrap(err, "查询订单列表失败")
	}

	// 构造返回结果
	items := make([]v1.OrderListItem, 0, len(orders))
	for _, order := range orders {
		items = append(items, v1.OrderListItem{
			OrderNo:         order.OrderNo,
			MerchantOrderId: order.MerchantOrderId,
			AccountId:       order.AccountId,
			AccountName:     order.AccountName,
			Amount:          order.Amount.InexactFloat64(),
			AlipayUrl:       order.AlipayUrl,
			CardNumber:      order.CardNumber,
			CardPassword:    order.CardPassword,
			Status:          consts.CamelOilOrderStatus(order.Status),
			PayStatus:       consts.CamelOilPayStatus(order.PayStatus),
			NotifyStatus:    consts.CamelOilNotifyStatus(order.NotifyStatus),
			NotifyCount:     order.NotifyCount,
			PaidAt:          order.PaidAt,
			LastCheckAt:     order.LastCheckAt,
			FailureReason:   order.FailureReason,
			CreatedAt:       order.CreatedAt,
			UpdatedAt:       order.UpdatedAt,
		})
	}

	res = &v1.ListOrderRes{}
	res.Total = total
	res.List = items

	return res, nil
}

// OrderDetail 查询订单详情
func (s *sCamelOil) OrderDetail(ctx context.Context, req *v1.OrderDetailReq) (res *v1.OrderDetailRes, err error) {
	// 查询订单信息
	var order *entity.V1CamelOilOrder
	err = dao.V1CamelOilOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CamelOilOrder.Columns().OrderNo, req.OrderNo).
		Scan(&order)
	if err != nil {
		return nil, gerror.Wrap(err, "查询订单失败")
	}
	if order == nil {
		return nil, gerror.New("订单不存在")
	}

	// 查询账号信息
	var account *entity.V1CamelOilAccount
	if order.AccountId > 0 {
		err = dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
			Where(dao.V1CamelOilAccount.Columns().Id, order.AccountId).
			Scan(&account)
		if err != nil {
			return nil, gerror.Wrap(err, "查询账号失败")
		}
	}

	res = &v1.OrderDetailRes{}

	// 填充订单信息
	res.OrderInfo.OrderNo = order.OrderNo
	res.OrderInfo.MerchantOrderId = order.MerchantOrderId
	res.OrderInfo.AccountId = order.AccountId
	res.OrderInfo.AccountName = order.AccountName
	res.OrderInfo.Amount = order.Amount.InexactFloat64()
	res.OrderInfo.AlipayUrl = order.AlipayUrl
	res.OrderInfo.Status = consts.CamelOilOrderStatus(order.Status)
	res.OrderInfo.PayStatus = consts.CamelOilPayStatus(order.PayStatus)
	res.OrderInfo.NotifyStatus = consts.CamelOilNotifyStatus(order.NotifyStatus)
	res.OrderInfo.NotifyCount = order.NotifyCount
	res.OrderInfo.PaidAt = order.PaidAt
	res.OrderInfo.LastCheckAt = order.LastCheckAt
	res.OrderInfo.Attach = order.Attach
	res.OrderInfo.FailureReason = order.FailureReason
	res.OrderInfo.CreatedAt = order.CreatedAt
	res.OrderInfo.UpdatedAt = order.UpdatedAt

	// 填充账号信息
	if account != nil {
		res.AccountInfo.AccountId = account.Id
		res.AccountInfo.AccountName = account.AccountName
		res.AccountInfo.Phone = maskPhone(account.Phone)
		res.AccountInfo.Status = consts.CamelOilAccountStatus(account.Status)
		res.AccountInfo.LastUsedAt = account.LastUsedAt
	}

	return res, nil
}

// ListPrefetchOrder 查询预拉取订单列表
func (s *sCamelOil) ListPrefetchOrder(ctx context.Context, req *v1.ListPrefetchOrderReq) (res *v1.ListPrefetchOrderRes, err error) {
	m := dao.V1CamelOilPrefetchOrder.Ctx(ctx).DB(config.GetDatabaseV1())

	// 构建查询条件
	if req.AccountId != 0 {
		m = m.Where(dao.V1CamelOilPrefetchOrder.Columns().AccountId, req.AccountId)
	}
	if req.AccountName != "" {
		m = m.WhereLike(dao.V1CamelOilPrefetchOrder.Columns().AccountName, "%"+req.AccountName+"%")
	}
	if req.Amount > 0 {
		m = m.Where(dao.V1CamelOilPrefetchOrder.Columns().Amount, req.Amount)
	}
	if req.PlatformOrderNo != "" {
		m = m.Where(dao.V1CamelOilPrefetchOrder.Columns().PlatformOrderNo, req.PlatformOrderNo)
	}
	if req.Status > 0 {
		m = m.Where(dao.V1CamelOilPrefetchOrder.Columns().Status, int(req.Status))
	}
	if len(req.DateRange) == 2 && req.DateRange[0] != nil && req.DateRange[1] != nil {
		m = m.WhereBetween(dao.V1CamelOilPrefetchOrder.Columns().CreatedAt, req.DateRange[0], req.DateRange[1])
	}

	// 排除已删除的记录
	m = m.WhereNull(dao.V1CamelOilPrefetchOrder.Columns().DeletedAt)

	// 查询总数
	total, err := m.Count()
	if err != nil {
		return nil, gerror.Wrap(err, "查询预拉取订单总数失败")
	}

	// 分页查询
	var orders []*entity.V1CamelOilPrefetchOrder
	err = m.Page(req.Current, req.PageSize).
		OrderDesc(dao.V1CamelOilPrefetchOrder.Columns().CreatedAt).
		Scan(&orders)
	if err != nil {
		return nil, gerror.Wrap(err, "查询预拉取订单列表失败")
	}

	// 构造返回结果
	items := make([]v1.PrefetchOrderListItem, 0, len(orders))
	for _, order := range orders {
		items = append(items, v1.PrefetchOrderListItem{
			Id:              order.Id,
			AccountId:       order.AccountId,
			AccountName:     order.AccountName,
			Amount:          order.Amount.InexactFloat64(),
			PlatformOrderNo: order.PlatformOrderNo,
			AlipayUrl:       order.AlipayUrl,
			Status:          consts.CamelOilPrefetchOrderStatus(order.Status),
			OrderNo:         order.OrderNo,
			MatchedAt:       order.MatchedAt,
			ExpireAt:        order.ExpireAt,
			FailureReason:   order.FailureReason,
			Remark:          order.Remark,
			CreatedAt:       order.CreatedAt,
			UpdatedAt:       order.UpdatedAt,
		})
	}

	res = &v1.ListPrefetchOrderRes{}
	res.Total = total
	res.List = items

	return res, nil
}

// ====================================================================================
// 辅助函数
// ====================================================================================

// ExportOrder 导出订单数据为Excel
func (s *sCamelOil) ExportOrder(ctx context.Context, req *v1.ExportOrderReq) (fileName string, content []byte, err error) {
	// 构建查询条件
	m := dao.V1CamelOilOrder.Ctx(ctx).DB(config.GetDatabaseV1())

	if req.MerchantOrderId != "" {
		m = m.Where(dao.V1CamelOilOrder.Columns().MerchantOrderId, req.MerchantOrderId)
	}
	if req.OrderNo != "" {
		m = m.Where(dao.V1CamelOilOrder.Columns().OrderNo, req.OrderNo)
	}
	if req.AccountId != 0 {
		m = m.Where(dao.V1CamelOilOrder.Columns().AccountId, req.AccountId)
	}
	if req.Status > 0 {
		m = m.Where(dao.V1CamelOilOrder.Columns().Status, int(req.Status))
	}
	if req.PayStatus > 0 {
		m = m.Where(dao.V1CamelOilOrder.Columns().PayStatus, int(req.PayStatus))
	}
	if len(req.DateRange) == 2 && req.DateRange[0] != nil && req.DateRange[1] != nil {
		m = m.WhereBetween(dao.V1CamelOilOrder.Columns().CreatedAt, req.DateRange[0], req.DateRange[1])
	}

	// 查询所有符合条件的订单
	var orders []*entity.V1CamelOilOrder
	err = m.OrderDesc(dao.V1CamelOilOrder.Columns().CreatedAt).Scan(&orders)
	if err != nil {
		return "", nil, gerror.Wrap(err, "查询订单列表失败")
	}

	// 收集所有账号ID
	accountIds := make([]int64, 0, len(orders))
	accountMap := make(map[int64]*entity.V1CamelOilAccount)
	for _, order := range orders {
		if order.AccountId > 0 {
			accountIds = append(accountIds, order.AccountId)
		}
	}

	// 批量查询账号信息
	if len(accountIds) > 0 {
		var accounts []*entity.V1CamelOilAccount
		err = dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
			WhereIn(dao.V1CamelOilAccount.Columns().Id, accountIds).
			Scan(&accounts)
		if err == nil {
			for _, account := range accounts {
				accountMap[account.Id] = account
			}
		}
	}

	// 创建Excel文件
	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			glog.Error(ctx, "关闭Excel文件失败", err)
		}
	}()

	// 设置工作表名称
	sheetName := "骆驼油订单数据"
	f.SetSheetName("Sheet1", sheetName)

	// 设置表头
	headers := []string{"订单ID", "系统订单号", "商户订单号", "手机号", "卡号", "卡密", "订单金额", "订单状态", "支付状态", "创建时间"}
	for i, header := range headers {
		cell := fmt.Sprintf("%s1", string(rune('A'+i)))
		f.SetCellValue(sheetName, cell, header)
	}

	// 填充数据
	for i, order := range orders {
		row := i + 2

		// 订单ID
		f.SetCellValue(sheetName, fmt.Sprintf("A%d", row), order.Id)

		// 系统订单号
		f.SetCellValue(sheetName, fmt.Sprintf("B%d", row), order.OrderNo)

		// 商户订单号
		f.SetCellValue(sheetName, fmt.Sprintf("C%d", row), order.MerchantOrderId)

		// 手机号
		phone := ""
		if account, exists := accountMap[order.AccountId]; exists && account != nil {
			phone = account.Phone
		}
		f.SetCellValue(sheetName, fmt.Sprintf("D%d", row), phone)

		// 卡号
		f.SetCellValue(sheetName, fmt.Sprintf("E%d", row), order.CardNumber)

		// 卡密
		f.SetCellValue(sheetName, fmt.Sprintf("F%d", row), order.CardPassword)

		// 订单金额
		f.SetCellValue(sheetName, fmt.Sprintf("G%d", row), order.Amount.InexactFloat64())

		// 订单状态
		statusText := s.getOrderStatusText(consts.CamelOilOrderStatus(order.Status))
		f.SetCellValue(sheetName, fmt.Sprintf("H%d", row), statusText)

		// 支付状态
		payStatusText := s.getPayStatusText(consts.CamelOilPayStatus(order.PayStatus))
		f.SetCellValue(sheetName, fmt.Sprintf("I%d", row), payStatusText)

		// 创建时间
		if order.CreatedAt != nil {
			f.SetCellValue(sheetName, fmt.Sprintf("J%d", row), order.CreatedAt.Format("Y-m-d H:i:s"))
		}
	}

	// 生成文件名
	fileName = fmt.Sprintf("骆驼油订单数据_%s.xlsx", gtime.Now().Format("Y-m-d_H-i-s"))

	// 保存到字节数组
	buf, err := f.WriteToBuffer()
	if err != nil {
		return "", nil, gerror.Wrap(err, "生成Excel文件失败")
	}

	return fileName, buf.Bytes(), nil
}

// getOrderStatusText 获取订单状态文本
func (s *sCamelOil) getOrderStatusText(status consts.CamelOilOrderStatus) string {
	switch status {
	case consts.CamelOilOrderStatusPending:
		return "待处理"
	case consts.CamelOilOrderStatusProcessing:
		return "处理中"
	case consts.CamelOilOrderStatusCompleted:
		return "已完成"
	case consts.CamelOilOrderStatusFailed:
		return "已失败"
	default:
		return "未知"
	}
}

// getPayStatusText 获取支付状态文本
func (s *sCamelOil) getPayStatusText(status consts.CamelOilPayStatus) string {
	switch status {
	case consts.CamelOilPaymentStatusUnpaid:
		return "未支付"
	case consts.CamelOilPaymentStatusPaid:
		return "已支付"
	case consts.CamelOilPaymentStatusRefunded:
		return "已退款"
	case consts.CamelOilPaymentStatusTimeout:
		return "已超时"
	default:
		return "未知"
	}
}

// maskPhone 手机号脱敏
func maskPhone(phone string) string {
	if len(phone) < 11 {
		return phone
	}
	return phone[:3] + "****" + phone[7:]
}
