package query

import (
	"context"
	"qnc-server/app/main/api/internal/svc"
	"qnc-server/app/main/api/internal/types"
	"qnc-server/app/main/model"
	"qnc-server/common/ctxdata"
	"qnc-server/common/xerr"

	"github.com/Masterminds/squirrel"
	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
)

type QueryListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewQueryListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryListLogic {
	return &QueryListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *QueryListLogic) QueryList(req *types.QueryListReq) (resp *types.QueryListResp, err error) {
	userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
	if getUidErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "订单列表查询, 获取用户信息失败, %+v", getUidErr)
	}

	// 构建子查询：查找在query表中有记录的order_id
	querySubQuery := squirrel.Select("order_id").From("query")

	// 构建子查询：查找在authorization表中状态为pending的order_id
	authSubQuery := squirrel.Select("order_id").
		From("authorization").
		Where(squirrel.Eq{"status": model.AuthorizationStatusPending})

	// 构建主查询条件
	build := l.svcCtx.OrderModel.SelectBuilder().Where(squirrel.And{
		squirrel.Eq{
			"user_id": userID,
		},
		squirrel.NotEq{
			"status": model.OrderStatusPending,
		},
		squirrel.Or{
			// 在query表中有记录
			squirrel.Expr("id IN (?)", querySubQuery),
			// 或者在query表中没有记录，但在authorization表中状态为pending
			squirrel.And{
				squirrel.Expr("id NOT IN (?)", querySubQuery),
				squirrel.Expr("id IN (?)", authSubQuery),
			},
		},
	})

	// 从订单表分页查询
	orderList, total, err := l.svcCtx.OrderModel.FindPageListByPageWithTotal(l.ctx, build, req.Page, req.PageSize, "create_time DESC")
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "订单列表查询, 查找订单列表错误, %+v", err)
	}

	var list []types.Query
	if len(orderList) > 0 {
		for _, orderModel := range orderList {
			var query types.Query
			query.CreateTime = orderModel.CreateTime.Format("2006-01-02 15:04:05")
			query.UpdateTime = orderModel.UpdateTime.Format("2006-01-02 15:04:05")
			// 设置订单ID
			query.OrderId = orderModel.Id
			query.UserId = orderModel.UserId
			query.OrderNo = orderModel.OrderNo
			// 获取商品信息
			product, findProductErr := l.svcCtx.ProductModel.FindOne(l.ctx, orderModel.ProductId)
			if findProductErr != nil {
				return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "订单列表查询, 获取商品信息失败, %+v", findProductErr)
			}
			query.ProductName = product.ProductName

			// 设置订单支付状态
			query.IsPaid = orderModel.Status == model.OrderStatusPaid

			// 判断订单是否已退款
			query.IsRefunded = orderModel.Status == model.OrderStatusRefunded

			// 查询查询状态
			queryInfo, findQueryErr := l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, orderModel.Id)
			if findQueryErr != nil && !errors.Is(findQueryErr, model.ErrNotFound) {
				return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "订单列表查询, 获取查询信息失败, %+v", findQueryErr)
			}
			if errors.Is(findQueryErr, model.ErrNotFound) {
				query.QueryState = "未创建"
				query.IsQueryCompleted = false

				// 获取授权状态
				authInfo, findAuthErr := l.svcCtx.AuthorizationModel.FindOneByOrderId(l.ctx, orderModel.Id)
				if findAuthErr != nil && !errors.Is(findAuthErr, model.ErrNotFound) {
					return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "订单列表查询, 获取授权信息失败, %+v", findAuthErr)
				}
				if errors.Is(findAuthErr, model.ErrNotFound) {
					query.IsAuthCompleted = true
				} else {
					// 授权存在
					query.IsAuthCompleted = authInfo.Status == model.AuthorizationStatusSuccess
				}
			} else {
				// 查询存在
				query.Id = queryInfo.Id
				query.QueryState = queryInfo.QueryState
				query.IsQueryCompleted = queryInfo.QueryState == model.QueryStateSuccess

				// 获取授权状态
				authInfo, findAuthErr := l.svcCtx.AuthorizationModel.FindOneByOrderId(l.ctx, orderModel.Id)
				if findAuthErr == nil {
					// 授权存在
					query.IsAuthCompleted = authInfo.Status == model.AuthorizationStatusSuccess
				} else {
					// 查询存在但授权不存在，视为已授权
					query.IsAuthCompleted = true
				}
			}

			list = append(list, query)
		}
	}

	return &types.QueryListResp{
		Total: total,
		List:  list,
	}, nil
}
