package hyt

import (
	"ai_scheduler/internal/config"
	errorcode "ai_scheduler/internal/data/error"
	toolManager "ai_scheduler/internal/domain/tools"
	toolPu "ai_scheduler/internal/domain/tools/hyt/product_upload"
	"ai_scheduler/internal/domain/workflow/runtime"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"strconv"
	"strings"
	"sync"

	"github.com/cloudwego/eino/compose"
)

const WorkflowIDProductUpload = "hyt.productUpload"

func init() {
	runtime.Register(WorkflowIDProductUpload, func(d *runtime.Deps) (runtime.Workflow, error) {
		return &productUpload{cfg: d.Conf, toolManager: d.ToolManager}, nil
	})
}

type productUpload struct {
	cfg         *config.Config
	toolManager *toolManager.Manager
	data        *ProductUploadWorkflowInput
}

type ProductUploadWorkflowInput struct {
	Text string `mapstructure:"text"`
}

func (o *productUpload) ID() string { return WorkflowIDProductUpload }

func (o *productUpload) Invoke(ctx context.Context, rec *runtime.WorkflowArgs) (map[string]any, error) {
	// 构建工作流
	runnable, err := o.buildWorkflow(ctx)
	if err != nil {
		return nil, err
	}

	o.data = &ProductUploadWorkflowInput{
		Text: rec.UserContent.Text,
	}
	// 工作流过程调用
	output, err := runnable.Invoke(ctx, o.data)
	if err != nil {
		errStr := err.Error()
		if u := errors.Unwrap(err); u != nil {
			errStr = u.Error()
		}
		return nil, errorcode.WorkflowErr(errStr)
	}

	fmt.Printf("workflow output: %v\n", output)

	return output, nil
}

// ProductIngestData 对应 HYTSupplierProductPropertyTemplateZH 的结构
type SupplierProductIngestData struct {
	BarCode         string   `json:"条码"`
	CategoryName    string   `json:"分类名称"`
	GoodsName       string   `json:"货品名称"`
	GoodsNum        string   `json:"货品编号"`
	GoodsArticleNum string   `json:"商品货号"`
	Brand           string   `json:"品牌"`
	Unit            string   `json:"单位"`
	Specs           string   `json:"规格参数"`
	Description     string   `json:"货品说明"`
	ShelfLife       string   `json:"保质期"`
	ShelfLifeUnit   string   `json:"保质期单位"`
	Link            string   `json:"链接"`
	Images          []string `json:"货品图片"`
	EPrice          string   `json:"电商销售价格"`
	SalesPrice      string   `json:"销售价"`
	SupplierPrice   string   `json:"供应商报价"`
	TaxRate         string   `json:"税率"`
	SupplierName    string   `json:"默认供应商"`
	WarehouseName   string   `json:"默认存放仓库"`
	Remark          string   `json:"备注"`
	Length          string   `json:"长"`
	Width           string   `json:"宽"`
	Height          string   `json:"高"`
	Weight          string   `json:"重量"`
	SpuName         string   `json:"SPU名称"`
	SpuCode         string   `json:"SPU编码"`
	Profit          string   `json:"利润"`
}

// ProductUploadContext Graph 执行上下文状态
type ProductUploadContext struct {
	mu            *sync.Mutex
	InputText     string
	IngestData    *SupplierProductIngestData
	UploadReq     *toolPu.ProductUploadRequest
	SupplierName  string
	WarehouseName string
	UploadResp    *toolPu.ProductUploadResponse
}

// buildWorkflow 构建基于 Graph 的并行工作流
func (o *productUpload) buildWorkflow(ctx context.Context) (compose.Runnable[*ProductUploadWorkflowInput, map[string]any], error) {
	g := compose.NewGraph[*ProductUploadWorkflowInput, map[string]any]()

	// 1. DataMapping 节点: 解析 JSON -> 填充基础 Request
	g.AddLambdaNode("data_mapping", compose.InvokableLambda(func(ctx context.Context, in *ProductUploadWorkflowInput) (*ProductUploadContext, error) {
		state := &ProductUploadContext{
			mu:        &sync.Mutex{}, // 初始化锁
			InputText: in.Text,
			UploadReq: &toolPu.ProductUploadRequest{
				GoodsList: make([]toolPu.Goods, 1), // 初始化一个商品
			},
		}

		// 解析用户输入的中文 JSON
		var ingestData SupplierProductIngestData
		if err := json.Unmarshal([]byte(in.Text), &ingestData); err != nil {
			return nil, fmt.Errorf("解析商品数据失败: %w", err)
		}

		// 必填校验
		if ingestData.SupplierName == "" {
			return nil, errors.New("供应商名称不能为空")
		}
		if ingestData.WarehouseName == "" {
			return nil, errors.New("仓库名称不能为空")
		}
		if ingestData.Profit == "" {
			return nil, errors.New("利润不能为空")
		}
		if ingestData.TaxRate == "" {
			return nil, errors.New("税率不能为空")
		}
		if ingestData.SupplierPrice == "" {
			return nil, errors.New("供应商报价不能为空")
		}

		state.IngestData = &ingestData
		state.SupplierName = ingestData.SupplierName
		state.WarehouseName = ingestData.WarehouseName

		// 映射字段到 UploadReq
		goodsInfo := &state.UploadReq.GoodsList[0].GoodsInfo
		goodsInfo.Title = ingestData.GoodsName
		goodsInfo.Brand = ingestData.Brand
		goodsInfo.Category = ingestData.CategoryName
		goodsInfo.GoodsBarCode = ingestData.BarCode
		goodsInfo.GoodsNum = ingestData.GoodsNum
		if goodsInfo.GoodsNum == "" {
			goodsInfo.GoodsNum = ingestData.GoodsArticleNum
		}
		goodsInfo.Unit = ingestData.Unit
		goodsInfo.GoodsAttributes = ingestData.Specs
		goodsInfo.Introduction = ingestData.Description
		goodsInfo.SpuName = ingestData.SpuName
		goodsInfo.SpuNum = ingestData.SpuCode
		goodsInfo.Weight = ingestData.Weight

		// 数值处理
		if val, err := strconv.ParseFloat(strings.TrimSuffix(ingestData.SalesPrice, "元"), 64); err == nil {
			goodsInfo.SalesPrice = val
		}
		if val, err := strconv.ParseFloat(strings.TrimSuffix(ingestData.EPrice, "元"), 64); err == nil {
			goodsInfo.Price = val // 假设电商价为市场价
		}
		// 价格兼容
		if goodsInfo.CostPrice == 0 {
			goodsInfo.CostPrice = goodsInfo.Price
		}
		// 税率处理 "13%" -> 13
		taxStr := strings.TrimSuffix(strings.TrimSuffix(ingestData.TaxRate, "%"), " ")
		if val, err := strconv.Atoi(taxStr); err == nil {
			goodsInfo.TaxRate = val
			state.UploadReq.TaxRate = val
		}
		// 利润处理
		if val, err := strconv.ParseFloat(strings.TrimSuffix(ingestData.Profit, "元"), 64); err == nil {
			state.UploadReq.Profit = val
		}

		// 图片处理
		for i, imgUrl := range ingestData.Images {
			state.UploadReq.GoodsList[0].GoodsMediaList = append(state.UploadReq.GoodsList[0].GoodsMediaList, toolPu.GoodsMedia{
				Url:  imgUrl,
				Type: 1, // 图片
				Sort: i,
			})
		}

		// 默认值字段
		goodsInfo.IsComposeGoods = 2
		goodsInfo.IsBind = 0
		goodsInfo.IsHot = 2
		state.UploadReq.IsDefaultWarehouse = 1
		state.UploadReq.Sort = 1

		return state, nil
	}))

	// 2. 获取供应商ID 节点
	g.AddLambdaNode("get_supplier_id", compose.InvokableLambda(func(ctx context.Context, state *ProductUploadContext) (*ProductUploadContext, error) {
		if state.SupplierName == "" {
			return state, errors.New("供应商名称不能为空")
		}

		supplierId, err := o.toolManager.Hyt.SupplierSearch.Call(ctx, state.SupplierName)
		if err != nil {
			// 记录日志，但不阻断流程，可能允许 ID 为 0
			log.Printf("warning: 供应商ID获取失败，%s: %v\n", state.SupplierName, err)
		} else {
			state.mu.Lock()
			defer state.mu.Unlock()
			state.UploadReq.SupplierId = supplierId
		}

		return state, nil
	}))

	// 3. 获取仓库ID 节点
	g.AddLambdaNode("get_warehouse_id", compose.InvokableLambda(func(ctx context.Context, state *ProductUploadContext) (*ProductUploadContext, error) {
		if state.WarehouseName == "" {
			return state, errors.New("仓库名称不能为空")
		}

		warehouseId, err := o.toolManager.Hyt.WarehouseSearch.Call(ctx, state.WarehouseName)
		if err != nil {
			log.Printf("warning: 仓库ID获取失败，%s: %v\n", state.WarehouseName, err)
		} else {
			state.mu.Lock()
			defer state.mu.Unlock()
			state.UploadReq.WarehouseId = warehouseId
		}

		return state, nil
	}))

	// 4. 合并/同步节点
	g.AddLambdaNode("merge_node", compose.InvokableLambda(func(ctx context.Context, state *ProductUploadContext) (*ProductUploadContext, error) {
		// 最终校验
		if state.UploadReq.SupplierId == 0 {
			return nil, fmt.Errorf("供应商获取失败")
		}
		if state.UploadReq.WarehouseId == 0 {
			return nil, fmt.Errorf("仓库获取失败")
		}
		return state, nil
	}))

	// 5. 上传节点
	g.AddLambdaNode("upload_product", compose.InvokableLambda(func(ctx context.Context, state *ProductUploadContext) (*ProductUploadContext, error) {
		toolRes, err := o.toolManager.Hyt.ProductUpload.Call(ctx, state.UploadReq)
		if err != nil {
			return nil, fmt.Errorf("商品上传失败")
		}
		state.UploadResp = toolRes
		return state, nil
	}))

	// 6. 结果格式化节点
	g.AddLambdaNode("format_output", compose.InvokableLambda(func(ctx context.Context, state *ProductUploadContext) (map[string]any, error) {
		if state.UploadResp == nil {
			return nil, fmt.Errorf("upload response is nil")
		}
		return map[string]any{
			"预览URL(货易通商品列表)": state.UploadResp.PreviewUrl,
			"SPU编码":          state.UploadResp.SpuNum,
			"商品ID":           state.UploadResp.Id,
		}, nil
	}))

	// 构建边
	// Start -> Mapping
	g.AddEdge(compose.START, "data_mapping")

	// 串行化执行以规避 Eino 指针合并问题
	// Mapping -> Supplier
	g.AddEdge("data_mapping", "get_supplier_id")

	// Supplier -> Warehouse
	g.AddEdge("get_supplier_id", "get_warehouse_id")

	// Warehouse -> Merge (虽然串行了，保留 Merge 节点做校验)
	g.AddEdge("get_warehouse_id", "merge_node")

	// Merge -> Upload
	g.AddEdge("merge_node", "upload_product")

	// Upload -> Format
	g.AddEdge("upload_product", "format_output")

	// Format -> END
	g.AddEdge("format_output", compose.END)

	return g.Compile(ctx)
}
