package camel_oil

import (
	"context"
	"fmt"
	v1 "kami/api/camel_oil/v1"
	"kami/internal/consts"
	"kami/internal/dao"
	"kami/internal/model/do"
	"kami/internal/model/entity"
	"kami/utility/config"

	"github.com/gogf/gf/v2/os/glog"
)

// ====================================================================================
// 订单历史记录管理
// ====================================================================================

// GetOrderHistory 获取订单历史记录
func (s *sCamelOil) GetOrderHistory(ctx context.Context, req *v1.OrderHistoryReq) (res *v1.OrderHistoryRes, err error) {
	// 1. 构建查询
	m := dao.V1CamelOilOrderHistory.Ctx(ctx).DB(config.GetDatabaseV1())
	m = m.Where(dao.V1CamelOilOrderHistory.Columns().OrderNo, req.OrderNo)

	// 2. 查询总数
	total, err := m.Count()
	if err != nil {
		glog.Error(ctx, "查询订单历史记录总数失败", err)
		return nil, err
	}

	// 3. 查询列表
	var histories []*entity.V1CamelOilOrderHistory
	err = m.Page(req.Current, req.PageSize).
		OrderDesc(dao.V1CamelOilOrderHistory.Columns().Id).
		Scan(&histories)

	if err != nil {
		glog.Error(ctx, "查询订单历史记录列表失败", err)
		return nil, err
	}

	// 4. 组装响应数据
	items := make([]v1.OrderHistoryItem, 0, len(histories))
	for _, history := range histories {
		items = append(items, v1.OrderHistoryItem{
			OrderNo:     history.OrderNo,
			ChangeType:  consts.CamelOilOrderChangeType(history.ChangeType),
			ChangeText:  getOrderChangeTypeText(history.ChangeType),
			AccountId:   history.AccountId,
			AccountName: history.AccountName,
			RawData:     history.RawData,
			Remark:      history.Remark,
			CreatedAt:   history.CreatedAt,
		})
	}

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

	return res, nil
}

// RecordOrderHistory 记录订单历史
func (s *sCamelOil) RecordOrderHistory(ctx context.Context, orderNo string, changeType consts.CamelOilOrderChangeType, rawData string, remark string) error {
	m := dao.V1CamelOilOrderHistory.Ctx(ctx).DB(config.GetDatabaseV1())

	_, err := m.Insert(&do.V1CamelOilOrderHistory{
		OrderNo:    orderNo,
		ChangeType: string(changeType),
		RawData:    rawData,
		Remark:     remark,
	})

	if err != nil {
		glog.Error(ctx, "记录订单历史失败", err)
		return err
	}

	return nil
}

// getOrderChangeTypeText 获取订单变更类型文本
func getOrderChangeTypeText(changeType string) string {
	changeTypeMap := map[string]string{
		"create":           "创建订单",
		"submit":           "提交到骆驼平台",
		"get_pay_url":      "获取支付链接",
		"check_pay":        "检测支付状态",
		"paid":             "支付成功",
		"timeout":          "支付超时",
		"fail":             "下单失败",
		"callback_success": "回调商户成功",
		"callback_fail":    "回调商户失败",
	}

	if text, ok := changeTypeMap[changeType]; ok {
		return text
	}
	return changeType
}

// GetAccountOrders 查询账号关联订单
func (s *sCamelOil) GetAccountOrders(ctx context.Context, req *v1.AccountOrderListReq) (res *v1.AccountOrderListRes, err error) {
	// 1. 获取账号信息
	var account *entity.V1CamelOilAccount
	err = dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CamelOilAccount.Columns().Id, req.AccountId).
		Scan(&account)
	if err != nil {
		glog.Error(ctx, "获取账号信息失败", err)
		return nil, err
	}
	if account == nil {
		return nil, fmt.Errorf("账号不存在")
	}

	// 2. 构建订单查询
	m := dao.V1CamelOilOrder.Ctx(ctx).DB(config.GetDatabaseV1())
	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 {
		m = m.WhereBetween(dao.V1CamelOilOrder.Columns().CreatedAt, req.DateRange[0], req.DateRange[1])
	}

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

	// 4. 查询订单列表
	var orders []*entity.V1CamelOilOrder
	err = m.Page(req.Current, req.PageSize).
		OrderDesc(dao.V1CamelOilOrder.Columns().Id).
		Scan(&orders)

	if err != nil {
		glog.Error(ctx, "查询订单列表失败", err)
		return nil, err
	}

	// 5. 统计订单数据
	orderStats, err := s.getOrderStats(ctx, req.AccountId)
	if err != nil {
		glog.Error(ctx, "统计订单数据失败", err)
	}

	// 6. 组装响应数据
	res = &v1.AccountOrderListRes{}

	// 账号基本信息
	res.AccountInfo.AccountId = account.Id
	res.AccountInfo.AccountName = account.AccountName
	res.AccountInfo.Phone = maskPhone(account.Phone)
	res.AccountInfo.Status = consts.CamelOilAccountStatus(account.Status)

	// 订单统计
	if orderStats != nil {
		res.OrderStats = orderStats.OrderStats
	}

	// 订单列表
	items := make([]v1.OrderListItem, 0, len(orders))
	for _, order := range orders {
		items = append(items, convertOrderToListItem(order))
	}

	// res.OrderList.List = items
	// res.OrderList.Total = total

	return res, nil
}

// getOrderStats 获取订单统计数据
func (s *sCamelOil) getOrderStats(ctx context.Context, accountId int64) (*v1.AccountOrderListRes, error) {
	m := dao.V1CamelOilOrder.Ctx(ctx).DB(config.GetDatabaseV1())
	m = m.Where(dao.V1CamelOilOrder.Columns().AccountId, accountId)

	totalOrders, _ := m.Clone().Count()
	paidOrders, _ := m.Clone().Where(dao.V1CamelOilOrder.Columns().PayStatus, 1).Count()
	pendingOrders, _ := m.Clone().Where(dao.V1CamelOilOrder.Columns().PayStatus, 0).Count()
	timeoutOrders, _ := m.Clone().Where(dao.V1CamelOilOrder.Columns().PayStatus, 3).Count()

	stats := &v1.AccountOrderListRes{}
	stats.OrderStats.TotalOrders = totalOrders
	stats.OrderStats.PaidOrders = paidOrders
	stats.OrderStats.PendingOrders = pendingOrders
	stats.OrderStats.TimeoutOrders = timeoutOrders

	return stats, nil
}

// convertOrderToListItem 将订单实体转换为列表项
func convertOrderToListItem(order *entity.V1CamelOilOrder) v1.OrderListItem {
	item := v1.OrderListItem{
		OrderNo:         order.OrderNo,
		MerchantOrderId: order.MerchantOrderId,
		AccountId:       order.AccountId,
		AccountName:     order.AccountName,
		Amount:          order.Amount.InexactFloat64(),
		AlipayUrl:       order.AlipayUrl,
		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,
	}

	return item
}
