package mgt

import (
	"context"
	"errors"
	"time"

	"bsm/full/module/ec/order/internal/impl"
	"bsm/full/module/ec/order/internal/logic/common"
	"bsm/full/module/ec/order/internal/models"
	pb "bsm/full/module/ec/order/pb"

	"git.apinb.com/bsm-sdk/core/errcode"
	"git.apinb.com/bsm-sdk/core/printer"
	"git.apinb.com/bsm-sdk/core/service"
	"git.apinb.com/bsm-sdk/core/utils"
	"gorm.io/gorm"
)

// 创建订单
func OrderCreate(ctx context.Context, in *pb.CreateOrderRequest) (reply *pb.OrderStatusReply, err error) {
	// parse authorization meta.
	auth, err := service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
	if err != nil {
		return nil, err
	}

	if auth.Owner == nil {
		return nil, errcode.ErrPermissionDenied
	}
	var (
		TotalPrice      int64  = 0
		summaryIdentity string = utils.UUID()
		orderNo                = common.CreateOrderNo()
		details                = &models.OrderDetails{}
		summary                = &models.OrderSummary{}
		specList               = make([]models.OrderDetails, 0)
	)

	// 验证输入参数是否有效。
	for _, spec := range in.Spec {
		if spec.GetProductIdentity() == "" || spec.GetNumber() == 0 {
			return nil, errcode.ErrInvalidArgument
		}
	}
	if in.GetAddressIdentity() == "" {
		return nil, errcode.ErrInvalidArgument
	}

	ownerStore := auth.Owner.(map[string]any)
	storeId := uint(ownerStore["store_id"].(float64))
	storeIdentity := ownerStore["store_identity"].(string)

	// 查询产品信息以确保其存在且状态为启用。
	for _, specs := range in.Spec {
		product := map[string]any{}
		err = impl.DBService.Table("mall_product").Take(&product, "identity=?", specs.ProductIdentity).Error
		if err != nil {
			printer.Error(err.Error())
			return nil, errcode.ErrDB
		}
		if product["status"].(int32) != 1 {
			return nil, errcode.ErrUnknown
		}
		// 查询产品规格信息。
		spec := map[string]any{}
		err = impl.DBService.Table("mall_product_spec").Take(&spec, "product_identity=? ", specs.ProductIdentity).Error
		if err != nil {
			printer.Error(err.Error())
			return nil, errcode.ErrDB
		}

		// 从产品信息中提取单价、ID等详情，并构建订单详情对象。
		productID := product["id"].(int64)
		unit_price := product["sales_price"].(int64)
		// 计算交易价格并构建订单摘要对象。
		itemTotal := int64(specs.Number) * unit_price
		TotalPrice += itemTotal
		details = &models.OrderDetails{
			SummaryIdentity: summaryIdentity,
			Type:            1,
			ProductID:       productID,
			ProductIdentity: product["identity"].(string),
			OrderNo:         orderNo,
			Title:           product["title"].(string),
			CoverImage:      product["cover_image"].(string),
			UnitPrice:       unit_price,
			Number:          specs.Number,
			ProductArgs:     product["args"].(string),
			SpecID:          spec["id"].(int64),
			SpecNo:          spec["serial_number"].(string),
			SpecTitle:       spec["title"].(string),
			SupplyId:        product["supply_id"].(int64),
			GasType:         product["gas_types"].(int32),
		}
		specList = append(specList, *details)
	}

	// 查询地址信息以确保其存在。
	address := map[string]any{}
	err = impl.DBService.Table("address_library").Take(&address, "identity=?", in.AddressIdentity).Error
	if err != nil {
		printer.Error(err.Error())
		return nil, errcode.ErrDB
	}

	summary = &models.OrderSummary{
		StoreID:         storeId,
		StoreIdentity:   storeIdentity,
		OrderNo:         orderNo,
		PartnerID:       in.PartnerId,
		TransPrice:      TotalPrice,
		TotalPrice:      TotalPrice,
		Args:            in.Args,
		County:          address["country"].(string),
		Province:        address["province"].(string),
		City:            address["city"].(string),
		Area:            address["area"].(string),
		Address:         address["detail"].(string),
		Contact:         address["contact"].(string),
		Phone:           address["phone"].(string),
		AddressIdentity: address["identity"].(string),
		OrderDetails:    specList,
	}
	summary.Identity = summaryIdentity
	summary.PassportID = auth.ID
	summary.PassportIdentity = auth.Identity
	summary.Status = 1

	// 将订单摘要和订单详情记录到数据库。
	err = impl.DBService.Transaction(func(tx *gorm.DB) error {
		// 创建订单摘要。
		if err := tx.Create(summary).Error; err != nil {
			printer.Error(err.Error())
			return err
		}

		// 扣减库存
		for _, v := range summary.OrderDetails {
			if v.Number > 0 {
				result := tx.Table("mall_product_spec").
					Where("id = ? AND stock >= ?", v.SpecID, v.Number).
					UpdateColumn("stock", gorm.Expr("stock - ?", v.Number))

				if result.Error != nil {
					return result.Error
				}

				// 检查实际更新的行数
				if result.RowsAffected == 0 {
					return errors.New("库存不足或规格不存在")
				}
			}
		}
		return nil
	})

	if err != nil {
		printer.Error(err.Error())
		return nil, errcode.ErrDB
	}

	return &pb.OrderStatusReply{
		Code:     0,
		Message:  "OK",
		Timeseq:  time.Now().UnixNano(),
		Identity: summary.Identity,
	}, nil

}
