package sale

import (
	"context"
	"git.kumo.work/shama/service/client"
	bean2 "git.kumo.work/shama/service/erp/bean"
	product2 "git.kumo.work/shama/service/erp/product"
	"git.kumo.work/shama/service/lib/bean"
	"github.com/shopspring/decimal"
	"time"
)

type product struct {
	product2.Product
}
type ArgsProductList struct {
	Page   bean.Page
	Search ProductSearch
}
type ProductSearch struct {
	PiSerial        string  // PiSerial
	PoSerial        string  // PoSerial
	CustomSerial    string  // 客户货号
	Serial          string  // 货号
	CreatedStaffIds []int64 // 录入人
	SaleIds         []int64 // 销售合同id
}
type ReplyProductList struct {
	Total int64             `json:"total"`
	List  []ProductListItem `json:"list"`
}
type ProductListItem struct {
	Id                 int64            `json:"id"`
	Mold               int64            `json:"mold"`
	ParentId           int64            `json:"parentId"`
	Serial             string           `json:"serial"`
	Po                 string           `json:"po"`
	CustomSerial       string           `json:"customSerial"`
	Name               string           `json:"name"`
	EngName            string           `json:"engName"`
	ImgFilePaths       []string         `json:"imgFilePaths"`
	Weight             *decimal.Decimal `json:"weight"`
	Texture            string           `json:"texture"`
	SalePrice          decimal.Decimal  `json:"salePrice"`
	BanFlag            int64            `json:"banFlag"`
	Type               string           `json:"type"`
	Barcode            string           `json:"barcode"`
	SellCountry        string           `json:"sellCountry"`
	Info               string           `json:"info"`
	Sort               int64            `json:"sort"`
	SaleCount          int64            `json:"saleCount"`
	SaleAmount         decimal.Decimal  `json:"saleAmount"`
	BoxCount           int64            `json:"boxCount"`
	QuotePrice         decimal.Decimal  `json:"quotePrice"`
	QuoteFactorySerial string           `json:"quoteFactorySerial"`
	QuoteFactoryId     int64            `json:"quoteFactoryId"`
	QuoteFactoryName   string           `json:"quoteFactoryName"`
	QuoteStartNum      int64            `json:"quoteStartNum"`
	QuoteMeasureUnit   string           `json:"quoteMeasureUnit"`
	OuterNum           *int64           `json:"outerNum"`
	Currency           string           `json:"currency"`
	CurrencyName       string           `json:"currencyName"`
	CurrencySymbol     string           `json:"currencySymbol"`
	CurrencyRate       decimal.Decimal  `json:"currencyRate"`
	PurchaseCount      int64            `json:"purchaseCount"`
	CreatedAt          *time.Time       `json:"createdAt"`
	UpdatedAt          *time.Time       `json:"updatedAt"`
	CreatedStaffId     int64            `json:"createdStaffId"`
	PiSerial           string           `json:"piSerial"`
	PoSerial           string           `json:"poSerial"`
	CustomShortName    string           `json:"customShortName"`
	CustomName         string           `json:"customName"`
	SaleCreatedAt      *time.Time       `json:"saleCreatedAt"`
	PurchasedCount     int64            `json:"purchasedCount"`
	ShipmentCount      int64            `json:"shipmentCount"`
	ShippedCount       int64            `json:"shippedCount"`
}

// List @TITLE 产品列表
func (p *product) List(ctx context.Context, args ArgsProductList) (reply ReplyProductList, err error) {
	xClient, err := client.GetClient(p)
	if err != nil {
		return
	}
	err = xClient.Call(ctx, "List", args, &reply)
	return
}

type ProductItem struct {
	Id                 int64            `json:"id"`
	Mold               int64            `json:"mold"`
	ParentId           int64            `json:"parentId"`
	Serial             string           `json:"serial"`
	Po                 string           `json:"po"`
	CustomSerial       string           `json:"customSerial"`
	Name               string           `json:"name"`
	EngName            string           `json:"engName"`
	ImgFilePaths       []string         `json:"imgFilePaths"`
	Weight             *decimal.Decimal `json:"weight"`
	Texture            string           `json:"texture"`
	SalePrice          decimal.Decimal  `json:"salePrice"`
	BanFlag            int64            `json:"banFlag"`
	Type               string           `json:"type"`
	Barcode            string           `json:"barcode"`
	SellCountry        string           `json:"sellCountry"`
	Info               string           `json:"info"`
	Sort               int64            `json:"sort"`
	SaleCount          int64            `json:"saleCount"`
	SaleAmount         decimal.Decimal  `json:"saleAmount"`
	BoxCount           int64            `json:"boxCount"`
	QuotePrice         decimal.Decimal  `json:"quotePrice"`
	QuoteFactorySerial string           `json:"quoteFactorySerial"`
	QuoteFactoryId     int64            `json:"quoteFactoryId"`
	QuoteFactoryName   string           `json:"quoteFactoryName"`
	QuoteStartNum      int64            `json:"quoteStartNum"`
	QuoteMeasureUnit   string           `json:"quoteMeasureUnit"`
	OuterNum           *int64           `json:"outerNum"`
	Currency           string           `json:"currency"`
	CurrencyName       string           `json:"currencyName"`
	CurrencySymbol     string           `json:"currencySymbol"`
	CurrencyRate       decimal.Decimal  `json:"currencyRate"`
	PurchaseCount      int64            `json:"purchaseCount"`
	PurchasedCount     int64            `json:"purchasedCount"`
	ShipmentCount      int64            `json:"shipmentCount"`
	ShippedCount       int64            `json:"shippedCount"`
	AccountingCount    int64            `json:"accountingCount"`
	AccountedCount     int64            `json:"accountedCount"`
	CreatedAt          *time.Time       `json:"createdAt"`
	UpdatedAt          *time.Time       `json:"updatedAt"`
	Children           []*ProductItem   `json:"children"`
}

// All @TITLE 获取产品
func (p *product) All(ctx context.Context, saleId int64) (reply []ProductItem, err error) {
	xClient, err := client.GetClient(p)
	if err != nil {
		return
	}
	err = xClient.Call(ctx, "All", saleId, &reply)
	return
}

type ArgsProductAdd struct {
	SaleId      int64        // 销售合同id
	ProductAdds []ProductAdd // 产品数组
}
type ProductAdd struct {
	ProductId             int64            // 产品id
	Serial                string           // 货号
	CustomSerial          string           // 客户货号
	Name                  string           // 中文品名
	EngName               string           // 英文品名
	Weight                *decimal.Decimal // 重量
	Texture               string           // 材质
	SalePrice             decimal.Decimal  // 销售单价
	BanFlag               int64            // 禁用标记 1=禁用,2=可用
	Mold                  int64            // 组成类型 1=单件 2=套件
	Type                  string           // 产品类型
	Barcode               string           // 条形码
	SellCountry           string           // 销售国家
	Info                  string           // 备注
	Description           string           // 中文描述
	EngDescription        string           // 英文描述
	PackageDescription    string           // 包装中文描述
	PackageEngDescription string           // 包装英文描述
	PackageInfoFile       bean2.FileData   // 包装描述文件
	Sort                  int64            // 排序
	SaleCount             int64            // 销售数量/合同数量
	Packages              []ProductPackage // 包装
	Customs               ProductCustoms   // 海关
	Quote                 ProductQuote     // 工厂报价
	ImgFilePaths          []string         // 图片地址集合
	Children              []ProductAdd     // 子组件
}

type ProductCustoms struct {
	Serial         string           // 海关编码
	Name           string           // 中文报关名称
	DomesticSupply string           // 境内货源地
	AddTaxRate     *decimal.Decimal // 增值税率
	MinusTaxRate   *decimal.Decimal // 退税率
	MeasureUnit    string           // 报关单位
	InvoiceUnit    string           // 开票单位
	Info           string           // 备注
	HsSerial       int64            // 是否商检 1=商检 2=未商检
	Brand          string           // 品牌
	Detail         string           // 报关要素
}
type ProductPackage struct {
	Type        int64            // 包装类型 1=内盒 2=外箱
	Material    string           // 材质
	Num         *int64           // 入数
	Length      *decimal.Decimal // 长
	Width       *decimal.Decimal // 宽
	Height      *decimal.Decimal // 高
	GrossWeight *decimal.Decimal // 毛重
	NetWeight   *decimal.Decimal // 净重
	Info        string           // 包装备注
}

type ProductQuote struct {
	FactorySerial  string          // 工厂货号
	FactoryId      int64           // 工厂id
	FactoryName    string          // 工厂名称
	Price          decimal.Decimal // 采购单价
	StartNum       int64           // 起订量
	MeasureUnit    string          // 数量单位
	Currency       string          // 币种
	CurrencyName   string          // 币种名称
	CurrencySymbol string          // 币种符号
	CurrencyRate   decimal.Decimal // 币种汇率
}

// Add @TITLE 添加商品
func (p *product) Add(ctx context.Context, args ArgsProductAdd) (err error) {
	xClient, err := client.GetClient(p)
	if err != nil {
		return
	}
	reply := 0
	return xClient.Call(ctx, "Add", args, &reply)
}

type ProductCustomsInfo struct {
	Id             int64            `json:"id"`
	Serial         string           `json:"serial"`
	Name           string           `json:"name"`
	DomesticSupply string           `json:"domesticSupply"`
	AddTaxRate     *decimal.Decimal `json:"addTaxRate"`
	MinusTaxRate   *decimal.Decimal `json:"minusTaxRate"`
	MeasureUnit    string           `json:"measureUnit"`
	InvoiceUnit    string           `json:"invoiceUnit"`
	Info           string           `json:"info"`
	HsSerial       int64            `json:"hsSerial"`
	Brand          string           `json:"brand"`
	Detail         string           `json:"detail"`
}

type ReplyProductInfo struct {
	Id                    int64                `json:"id"`
	ProductId             int64                `json:"productId"`
	Mold                  int64                `json:"mold"`
	Serial                string               `json:"serial"`
	CustomSerial          string               `json:"customSerial"`
	Name                  string               `json:"name"`
	EngName               string               `json:"engName"`
	ImgFilePaths          []string             `json:"imgFilePaths"`
	Weight                *decimal.Decimal     `json:"weight"`
	Texture               string               `json:"texture"`
	SalePrice             decimal.Decimal      `json:"salePrice"`
	BanFlag               int64                `json:"banFlag"`
	Type                  string               `json:"type"`
	Barcode               string               `json:"barcode"`
	SellCountry           string               `json:"sellCountry"`
	Info                  string               `json:"info"`
	Description           string               `json:"description"`
	EngDescription        string               `json:"engDescription"`
	PackageDescription    string               `json:"packageDescription"`
	PackageEngDescription string               `json:"packageEngDescription"`
	PackageInfoFile       bean2.FileData       `json:"packageInfoFile"`
	PurchaseCount         int64                `json:"purchaseCount"`
	PurchasedCount        int64                `json:"purchasedCount"`
	ShipmentCount         int64                `json:"shipmentCount"`
	ShippedCount          int64                `json:"shippedCount"`
	AccountingCount       int64                `json:"accountingCount"`
	AccountedCount        int64                `json:"accountedCount"`
	CreatedAt             *time.Time           `json:"createdAt"`
	UpdatedAt             *time.Time           `json:"updatedAt"`
	Packages              []ProductPackageInfo `json:"packages"`
	Customs               ProductCustomsInfo   `json:"customs"`
	Quote                 ProductQuoteInfo     `json:"quote"`
	Children              []ReplyProductInfo   `json:"children"`
}

type ProductPackageInfo struct {
	Type        int64            `json:"type"`
	Material    string           `json:"material"`
	Num         *int64           `json:"num"`
	Length      *decimal.Decimal `json:"length"`
	Width       *decimal.Decimal `json:"width"`
	Height      *decimal.Decimal `json:"height"`
	Volume      *decimal.Decimal `json:"volume"`
	GrossWeight *decimal.Decimal `json:"grossWeight"`
	NetWeight   *decimal.Decimal `json:"netWeight"`
	Info        string           `json:"info"`
}

type ProductQuoteInfo struct {
	Id             int64           `json:"id"`
	FactorySerial  string          `json:"factorySerial"`
	FactoryId      int64           `json:"factoryId"`
	FactoryName    string          `json:"factoryName"`
	Price          decimal.Decimal `json:"price"`
	StartNum       int64           `json:"startNum"`
	MeasureUnit    string          `json:"measureUnit"`
	Currency       string          `json:"currency"`
	CurrencyName   string          `json:"currencyName"`
	CurrencySymbol string          `json:"currencySymbol"`
	CurrencyRate   decimal.Decimal `json:"currencyRate"`
	CreatedAt      *time.Time      `json:"createdAt"`
	UpdatedAt      *time.Time      `json:"updatedAt"`
}

// Info @TITLE 产品详情
func (p *product) Info(ctx context.Context, saleProductId int64) (reply ReplyProductInfo, err error) {
	xClient, err := client.GetClient(p)
	if err != nil {
		return
	}
	err = xClient.Call(ctx, "Info", saleProductId, &reply)
	return
}

// Infos @TITLE 产品详情
func (p *product) Infos(ctx context.Context, saleProductIds []int64) (reply []ReplyProductInfo, err error) {
	xClient, err := client.GetClient(p)
	if err != nil {
		return
	}
	err = xClient.Call(ctx, "Infos", saleProductIds, &reply)
	return
}

type ArgsProductEdit struct {
	SaleProductId int64 // 产品ID
	ProductEdit
}

type ProductEdit struct {
	Serial                string           // 货号
	CustomSerial          string           // 客户货号
	Name                  string           // 中文品名
	EngName               string           // 英文品名
	Weight                *decimal.Decimal // 重量
	Texture               string           // 材质
	SalePrice             decimal.Decimal  // 销售单价
	BanFlag               int64            // 禁用标记 1=禁用,2=可用
	Mold                  int64            // 组成类型 1=单件 2=套件
	Type                  string           // 产品类型
	Barcode               string           // 条形码
	SellCountry           string           // 销售国家
	Info                  string           // 备注
	Description           string           // 中文描述
	EngDescription        string           // 英文描述
	PackageDescription    string           // 包装中文描述
	PackageEngDescription string           // 包装英文描述
	PackageInfoFile       bean2.FileData   // 包装描述文件
	Packages              []ProductPackage // 包装
	Customs               ProductCustoms   // 海关
	Quote                 ProductQuote     // 工厂报价
	ImgFilePaths          []string         // 图片地址集合
}

// Edit @TITLE 编辑产品
func (p *product) Edit(ctx context.Context, args ArgsProductEdit) (err error) {
	xClient, err := client.GetClient(p)
	if err != nil {
		return
	}
	reply := 0
	return xClient.Call(ctx, "Edit", args, &reply)
}

type MultiData struct {
	SaleProductId int64           // 产品id
	PO            string          // PO
	QuotePrice    decimal.Decimal // 采购单价
	SalePrice     decimal.Decimal // 销售单价
	SaleCount     int64           // 销售数量
	Info          string          // 备注
}

// MultiEdit @TITLE 批量编辑
func (p *product) MultiEdit(ctx context.Context, args []MultiData) (err error) {
	xClient, err := client.GetClient(p)
	if err != nil {
		return
	}
	reply := 0
	return xClient.Call(ctx, "MultiEdit", args, &reply)
}

// Delete @TITLE 删除产品
func (p *product) Delete(ctx context.Context, saleProductIds []int64) (err error) {
	xClient, err := client.GetClient(p)
	if err != nil {
		return
	}
	reply := 0
	return xClient.Call(ctx, "Delete", saleProductIds, &reply)
}