package summary

import (
	"context"
	"errors"
	"log"
	"strings"
	"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/types"
	"git.apinb.com/bsm-sdk/core/utils"
	"gorm.io/gorm"
)

// 将购物车的数据提交生成订单
func Submit(ctx context.Context, in *pb.SubmitRequest) (reply *pb.OrderStatusReply, err error) {
	// parse authorization meta.
	RoleValve := &service.ParseOptions{RoleValue: "Mall_Admin"}
	if in.GetAddress() != nil {
		RoleValve = nil
	}
	auth, err := service.ParseMetaCtx(ctx, RoleValve)
	if err != nil {
		return nil, err
	}

	var (
		cart         = make([]*models.OrderCart, 0)
		details      = make([]*models.OrderDetails, 0)
		summary      = make([]*models.OrderSummary, 0)
		keys         = make([]string, 0)
		address      = models.OrderAddress{}
		StoreId uint = 0
	)

	// 获取购物车内数据信息
	err = impl.DBService.Where("passport_identity = ?", auth.Identity).Find(&cart).Error
	if err != nil {
		printer.Error(err.Error())
		if errors.Is(err, models.ErrNotFound) {
			return nil, errcode.ErrRecordNotFound
		}
		return nil, errcode.ErrDB
	}

	// 获取地址信息
	if in.GetAddress() != nil {
		address = models.OrderAddress{
			Country:  in.Address.Country,
			Province: in.Address.Province,
			City:     in.Address.City,
			Detail:   in.Address.Detail,
			Contact:  in.Address.Contact,
			Phone:    in.Address.Phone,
			Area:     in.Address.Area,
			Email:    in.Address.Email,
			ZipCode:  in.Address.ZipCode,
		}
	} else {
		err = impl.DBService.Table("address_library").Where("identity = ?", in.AddressIdentity).Find(&address).Error
		if err != nil {
			printer.Error(err.Error())
			if errors.Is(err, models.ErrNotFound) {
				return nil, errcode.ErrRecordNotFound
			}
			return nil, errcode.ErrDB
		}
	}

	// 按店铺分组购物车商品
	storeGroups := make(map[string][]*models.OrderCart)
	for k, item := range cart {
		product := models.Product{}
		err = impl.DBService.Select("store_identity").Table("mall_product").Where("id = ?", item.ProductID).First(&product).Error
		if err != nil {
			printer.Error(err.Error())
			if errors.Is(err, models.ErrNotFound) {
				return nil, errcode.ErrRecordNotFound
			}
			return nil, errcode.ErrDB
		}

		if k == 0 {
			StoreId = product.StoreId
		}
		storeGroups[product.StoreIdentity] = append(storeGroups[product.StoreIdentity], item)
	}

	// 处理每个店铺
	for StoreIdentity, items := range storeGroups {
		var storeTotal int64 = 0
		var storeDetails []*models.OrderDetails

		//订单号：2位年份，月，日，时，分，秒，6位随机数共18位
		summaryIdentity := utils.UUID()
		orderNo := common.CreateOrderNo()

		// 处理店铺内所有商品
		for _, item := range items {
			product := models.Product{}
			spec := models.Spec{}

			// 获取产品信息
			err = impl.DBService.Select("title,cover_image,cost_price,supply_id,args,gas_types").Table("mall_product").
				Where("id = ?", item.ProductID).First(&product).Error
			if err != nil {
				printer.Error(err.Error())
				if errors.Is(err, models.ErrNotFound) {
					return nil, errcode.ErrRecordNotFound
				}
				return nil, errcode.ErrDB
			}

			// 获取规格信息
			err := impl.DBService.Select("title,serial_number,price").Table("mall_product_spec").
				Where("id = ?", item.SpecID).First(&spec).Error
			if err != nil {
				printer.Error(err.Error())
				if errors.Is(err, models.ErrNotFound) {
					return nil, errcode.ErrRecordNotFound
				}
				return nil, errcode.ErrDB
			}

			// 计算商品总价
			itemTotal := int64(item.Number) * spec.Price
			storeTotal += itemTotal

			// 添加到订单详情
			storeDetails = append(storeDetails, &models.OrderDetails{
				Type:            1,
				ProductID:       item.ProductID,
				ProductIdentity: item.ProductIdentity,
				SpecID:          item.SpecID,
				OrderNo:         orderNo,
				Title:           product.Title,
				CoverImage:      product.CoverImage,
				UnitPrice:       spec.Price,
				SalesPrice:      spec.Price,
				Number:          item.Number,
				ProductArgs:     item.ProductArgs,
				SummaryIdentity: summaryIdentity,
				SpecTitle:       spec.Title,
				SpecNo:          spec.SerialNumber,
				GasType:         int32(product.GasTypes),
				SupplyId:        product.SupplyId,
				TotalPrice:      int64(item.Number) * spec.Price,
			})
		}

		// 创建店铺订单摘要
		summary = append(summary, &models.OrderSummary{
			OrderNo:         orderNo,
			Std_Identity:    types.Std_Identity{Identity: summaryIdentity},
			PartnerID:       in.PartnerId,
			TransPrice:      storeTotal,
			TotalPrice:      storeTotal,
			StoreID:         StoreId,
			StoreIdentity:   StoreIdentity,
			LogisticsFee:    0,
			Remark:          "",
			AddressIdentity: in.AddressIdentity,
			County:          address.Country,
			Province:        address.Province,
			City:            address.City,
			Area:            address.Area,
			Address:         address.Detail,
			Contact:         address.Contact,
			Phone:           address.Phone,
			Std_Passport:    types.Std_Passport{PassportID: auth.ID, PassportIdentity: auth.Identity},
			Status:          1,
		})

		// 添加到总详情列表
		details = append(details, storeDetails...)
		keys = append(keys, StoreIdentity)
	}

	err = impl.DBService.Transaction(func(tx *gorm.DB) error {
		// 1. 创建订单摘要
		if err := tx.Create(summary).Error; err != nil {
			printer.Error(err.Error())
			return err
		}

		// 2. 创建订单详情
		if err := tx.Model(&models.OrderDetails{}).CreateInBatches(details, len(details)).Error; err != nil {
			printer.Error(err.Error())
			return err
		}

		// 3. 扣减库存
		for _, detail := range details {
			if detail.Number > 0 {
				var stock int32
				result := tx.Table("mall_product_spec").Select("stock").Where("id = ?", detail.SpecID).Scan(&stock)
				if result.Error != nil || stock < detail.Number {
					log.Printf("Insufficient stock or spec does not exist: %v", result.Error)
					return errors.New("库存不足或规格不存在")
				}
				updateErr := tx.Table("mall_product_spec").
					Where("id = ? AND stock >= ?", detail.SpecID, detail.Number).
					UpdateColumn("stock", gorm.Expr("stock - ?", detail.Number)).
					Error
				if updateErr != nil {
					printer.Error(updateErr.Error())
					return updateErr
				}
			}
		}

		// 4. 清空购物车
		if err := tx.Where("passport_identity = ?", auth.Identity).
			Delete(&models.OrderCart{}).Error; err != nil {
			printer.Error(err.Error())
			return err
		}

		return nil
	})

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

	// 返回第一个订单号作为标识
	firstOrderNo := ""
	if len(summary) > 0 {
		firstOrderNo = summary[0].OrderNo
	}

	return &pb.OrderStatusReply{
		Code:     0,
		Identity: firstOrderNo,
		Message:  strings.Join(keys, ","),
		Timeseq:  time.Now().UnixNano(),
	}, nil
}
