package routers

import (
	"context"
	"encoding/json"
	parsefmt "fmt"
	"ops/agents"
	"ops/models"
	"slices"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

var (
	purchaseUserGroup TabUserGroups
	purchaseAdmins    []uint
)

// 更新管理员成员缓存
func PurchaseUpdateAdminsCash() {
	purchaseAdmins = nil
	// id 1 是系统管理员
	purchaseAdmins = append(purchaseAdmins, 1)
	var binds []TabUserGroupBinds
	models.DB.Where("group_id = ?", purchaseUserGroup.ID).Find(&binds)
	for _, item := range binds {
		if !slices.Contains(purchaseAdmins, item.UserID) {
			purchaseAdmins = append(purchaseAdmins, item.UserID)
		}
	}
}

// 判断用户是否有权限修改/删除订单（创建者或管理员）
func canModifyPurchase(userID, creatorUserID uint) bool {
	if slices.Contains(purchaseAdmins, userID) {
		return true
	}
	if userID == creatorUserID {
		return true
	}
	return false
}

// decodeJSON 将 map 通过 JSON 中转解码到目标结构体，绕过 mapstructure 的字段名匹配问题
func decodeJSON(data map[string]interface{}, out interface{}) error {
	jsonBytes, err := json.Marshal(data)
	if err != nil {
		return err
	}
	return json.Unmarshal(jsonBytes, out)
}

type CostItem struct {
	Cost         int `json:"cost"`         // 费用（分）
	CostT        int `json:"costt"`        // 总价
	CurrencyType int `json:"currencytype"` // 货币类型: 1-CNY 2-MOP 3-HKD 4-USD
	Int          int `json:"int"`          // 数量
	Type         int `json:"type"`         // 费用类型: 1-单价 2-运费
}
type From_purchase_addorder struct {
	Costs       []CostItem `json:"costs"`        //  成本
	Link        string     `json:"link"`         //  链接
	OrderStatus string     `json:"order_status"` //  订单状态
	Photos      []string   `json:"photos"`       //  图片备注
	Remark      string     `json:"remark"`       //  备注
	Styles      string     `json:"styles"`       //  样式备注
	Title       string     `json:"title"`        //  标题
}

type TabPurchaseOrder struct {
	ID          uint           `gorm:"primarykey"`
	UserID      uint           `gorm:"not null"`
	Title       string         `gorm:"size:200;comment:标题"`
	Remark      string         `gorm:"type:text;comment:备注"`
	Link        string         `gorm:"size:1000;comment:链接"`
	Styles      string         `gorm:"type:text;comment:样式数组"`
	OrderStatus string         `gorm:"size:50;default:pending;comment:订单状态: pending-待处理 ordered-已下单 arrived-已到达 received-已收件 lost-丢件 returned-退件"`
	CreatedAt   *time.Time     `gorm:"type:datetime;autoCreateTime"`
	UpdatedAt   *time.Time     `gorm:"type:datetime;autoUpdateTime"`
	DeletedAt   gorm.DeletedAt `gorm:"index"`
}

type TabPurchaseCosts struct {
	ID           uint       `gorm:"primarykey"`
	OrderID      uint       `gorm:"not null"`
	UserID       uint       `gorm:"not null"`
	Price        int        `gorm:"not null"`
	Quantity     int        `gorm:"not null"`
	CurrencyType int        `gorm:"default:1;comment:货币类型: 1-CNY 2-MOP 3-HKD 4-USD"`
	CostType     int        `gorm:"default:1;comment:费用类型: 1-单价 2-运费"`
	CreatedAt    *time.Time `gorm:"type:datetime;autoCreateTime"`
}

// TabPurchaseCommit 记录订单状态变更及评论
type TabPurchaseCommit struct {
	ID        uint       `gorm:"primarykey"`
	OrderID   uint       `gorm:"not null;index;comment:关联订单ID"`
	UserID    uint       `gorm:"not null;comment:操作人ID"`
	Action    string     `gorm:"size:50;not null;comment:操作类型: create-创建 create_status-状态变更"`
	Status    string     `gorm:"size:50;comment:变更后的状态"`
	OldStatus string     `gorm:"size:50;comment:变更前的状态"`
	Comment   string     `gorm:"type:text;comment:评论/备注"`
	Photos    string     `gorm:"type:text;comment:变更图片(JSON数组，存放sha256哈希)"`
	IP        string     `gorm:"size:50;comment:操作IP"`
	CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"`
}

type TabPurchaseLog struct {
	ID         uint   `gorm:"primarykey"`
	OrderID    uint   `gorm:"not null;index;comment:关联OrderID"`
	UserID     uint   `gorm:"not null;comment:操作人ID"`
	ActionType string `gorm:"size:50;not null;comment:操作类型: create-创建 update-修改 delete-删除 query-查询"`
	OldContent string `gorm:"type:text;comment:修改前内容(JSON)"`
	NewContent string `gorm:"type:text;comment:修改后内容(JSON)"`
	IP         string `gorm:"size:50;comment:操作IP"`
	Remark     string `gorm:"size:500;comment:备注/操作描述"`

	CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime;comment:操作时间"`
}

type purchaseProvider struct{}

func (purchaseProvider) QueryPurchases(ctx context.Context, query agents.PurchaseQuery) (*agents.PurchaseQueryResult, error) {
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	default:
	}

	result := &agents.PurchaseQueryResult{
		Ok:       true,
		Action:   query.Action,
		LoggedIn: query.UserID > 0,
	}
	if !result.LoggedIn {
		result.Message = "需要登录才能查询采购模块信息。"
		return result, nil
	}

	switch query.Action {
	case "count":
		counts, err := queryPurchaseCounts(query)
		if err != nil {
			return nil, err
		}
		result.Counts = counts
		return result, nil
	case "get":
		order, err := queryPurchaseOrderDetail(query.OrderID, query.UserID)
		if err != nil {
			return nil, err
		}
		result.Order = order
		if order != nil {
			result.Count = 1
		}
		return result, nil
	default:
		orders, total, err := queryPurchaseOrderList(query)
		if err != nil {
			return nil, err
		}
		result.Orders = orders
		result.Count = len(orders)
		result.Total = total
		result.Page = query.Page
		result.Limit = query.Limit
		result.Filters = map[string]interface{}{
			"search":     query.Search,
			"status":     query.Status,
			"start_date": query.StartDate,
			"end_date":   query.EndDate,
		}
		return result, nil
	}
}

func applyPurchaseQueryFilters(db *gorm.DB, query agents.PurchaseQuery) (*gorm.DB, error) {
	if query.Search != "" {
		var id uint
		if _, err := parsefmt.Sscanf(query.Search, "%d", &id); err == nil && id > 0 {
			db = db.Where("id = ?", id)
		} else {
			db = db.Where("title LIKE ? OR remark LIKE ?", "%"+query.Search+"%", "%"+query.Search+"%")
		}
	}
	if query.Status != "" {
		db = db.Where("order_status = ?", query.Status)
	}
	if query.StartDate != "" {
		startDate, err := time.Parse("2006-01-02", query.StartDate)
		if err != nil {
			return nil, err
		}
		db = db.Where("created_at >= ?", startDate)
	}
	if query.EndDate != "" {
		endDate, err := time.Parse("2006-01-02", query.EndDate)
		if err != nil {
			return nil, err
		}
		db = db.Where("created_at < ?", endDate.AddDate(0, 0, 1))
	}
	return db, nil
}

func queryPurchaseOrderList(query agents.PurchaseQuery) ([]agents.PurchaseOrder, int64, error) {
	db, err := applyPurchaseQueryFilters(models.DB.Model(&TabPurchaseOrder{}), query)
	if err != nil {
		return nil, 0, err
	}
	var total int64
	if err := db.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	var rows []TabPurchaseOrder
	if err := db.Order("id DESC").Offset(query.Limit * (query.Page - 1)).Limit(query.Limit).Find(&rows).Error; err != nil {
		return nil, 0, err
	}

	orders := make([]agents.PurchaseOrder, 0, len(rows))
	for _, row := range rows {
		order, err := queryPurchaseOrderDetail(row.ID, query.UserID)
		if err != nil {
			return nil, 0, err
		}
		if order != nil {
			orders = append(orders, *order)
		}
	}
	return orders, total, nil
}

func queryPurchaseOrderDetail(orderID uint, userID uint) (*agents.PurchaseOrder, error) {
	var row TabPurchaseOrder
	if err := models.DB.Where("id = ?", orderID).First(&row).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, err
	}
	order := buildPurchaseOrder(row, userID)

	var costs []TabPurchaseCosts
	if err := models.DB.Where("order_id = ?", orderID).Order("id asc").Find(&costs).Error; err != nil {
		return nil, err
	}
	order.Costs = make([]agents.PurchaseCost, 0, len(costs))
	for _, cost := range costs {
		order.Costs = append(order.Costs, agents.PurchaseCost{
			ID:           cost.ID,
			OrderID:      cost.OrderID,
			UserID:       cost.UserID,
			Price:        cost.Price,
			Quantity:     cost.Quantity,
			CurrencyType: cost.CurrencyType,
			CurrencyName: purchaseCurrencyName(cost.CurrencyType),
			CostType:     cost.CostType,
			CostTypeName: purchaseCostTypeName(cost.CostType),
		})
	}

	var commits []TabPurchaseCommit
	if err := models.DB.Where("order_id = ?", orderID).Order("created_at DESC").Find(&commits).Error; err != nil {
		return nil, err
	}
	order.Commits = make([]agents.PurchaseCommit, 0, len(commits))
	for _, commit := range commits {
		order.Commits = append(order.Commits, agents.PurchaseCommit{
			ID:        commit.ID,
			OrderID:   commit.OrderID,
			UserID:    commit.UserID,
			Action:    commit.Action,
			Status:    commit.Status,
			OldStatus: commit.OldStatus,
			Comment:   commit.Comment,
			CreatedAt: formatTimePtr(commit.CreatedAt),
		})
	}
	return &order, nil
}

func queryPurchaseCounts(query agents.PurchaseQuery) (map[string]int64, error) {
	counts := map[string]int64{}
	statuses := []string{"pending", "ordered", "arrived", "received", "lost", "returned"}
	var total int64
	base, err := applyPurchaseQueryFilters(models.DB.Model(&TabPurchaseOrder{}), agents.PurchaseQuery{Search: query.Search, StartDate: query.StartDate, EndDate: query.EndDate})
	if err != nil {
		return nil, err
	}
	if err := base.Count(&total).Error; err != nil {
		return nil, err
	}
	counts["total"] = total
	for _, status := range statuses {
		statusQuery := agents.PurchaseQuery{Search: query.Search, Status: status, StartDate: query.StartDate, EndDate: query.EndDate}
		db, err := applyPurchaseQueryFilters(models.DB.Model(&TabPurchaseOrder{}), statusQuery)
		if err != nil {
			return nil, err
		}
		var count int64
		if err := db.Count(&count).Error; err != nil {
			return nil, err
		}
		counts[status] = count
	}
	return counts, nil
}

func buildPurchaseOrder(row TabPurchaseOrder, currentUserID uint) agents.PurchaseOrder {
	return agents.PurchaseOrder{
		ID:              row.ID,
		UserID:          row.UserID,
		Title:           row.Title,
		Remark:          row.Remark,
		Link:            row.Link,
		DetailURL:       purchaseOrderDetailURL(row.ID),
		Styles:          row.Styles,
		OrderStatus:     row.OrderStatus,
		OrderStatusName: purchaseStatusName(row.OrderStatus),
		CreatedAt:       formatTimePtr(row.CreatedAt),
		UpdatedAt:       formatTimePtr(row.UpdatedAt),
		CanModify:       canModifyPurchase(currentUserID, row.UserID),
	}
}

func purchaseOrderDetailURL(orderID uint) string {
	return parsefmt.Sprintf("/purchase/showorder/%d", orderID)
}

func formatTimePtr(t *time.Time) string {
	if t == nil {
		return ""
	}
	return t.Format("2006-01-02 15:04:05")
}

func purchaseStatusName(status string) string {
	switch status {
	case "pending":
		return "待处理"
	case "ordered":
		return "已下单"
	case "arrived":
		return "已到达"
	case "received":
		return "已收件"
	case "lost":
		return "丢件"
	case "returned":
		return "退件"
	default:
		return status
	}
}

func purchaseCurrencyName(currencyType int) string {
	switch currencyType {
	case 1:
		return "CNY"
	case 2:
		return "MOP"
	case 3:
		return "HKD"
	case 4:
		return "USD"
	default:
		return "未知"
	}
}

func purchaseCostTypeName(costType int) string {
	switch costType {
	case 1:
		return "单价"
	case 2:
		return "运费"
	default:
		return "未知"
	}
}

func ApiPurchaseInit() {

	models.DB.AutoMigrate(&TabPurchaseOrder{})
	models.DB.AutoMigrate(&TabPurchaseCosts{})

	models.DB.AutoMigrate(&TabPurchaseLog{})
	models.DB.AutoMigrate(&TabPurchaseCommit{})

	//先检查用户组有没有这个key  purchase
	purchaseUserGroup.Name = "purchase_admin"
	if models.DB.Where(&purchaseUserGroup).First(&purchaseUserGroup).Error == nil {
		PurchaseUpdateAdminsCash()
	} else {
		purchaseUserGroup.Type = "usergroup"
		models.DB.Create(&purchaseUserGroup)
	}

	agents.RegisterPurchaseProvider(purchaseProvider{})
}

func ApiPurchase(r *gin.RouterGroup) {

	r.POST("/getorder", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userCookieError", nil)
			return
		}

		type FromGetOrder struct {
			ID uint `json:"id"`
		}
		var from FromGetOrder
		if err := decodeJSON(data, &from); err != nil || from.ID == 0 {
			ReturnJson(ctx, "jsonErr", nil)
			return
		}

		var order TabPurchaseOrder
		if err := models.DB.Where("id = ?", from.ID).First(&order).Error; err != nil {
			ReturnJson(ctx, "order_not_found", nil)
			return
		}

		// 查询关联费用
		var costs []TabPurchaseCosts
		models.DB.Where("order_id = ?", from.ID).Find(&costs)

		// 查询关联图片
		var binds []TabPurchaseFileBind
		models.DB.Where("order_id = ?", from.ID).Find(&binds)
		var fileIDs []uint
		for _, b := range binds {
			fileIDs = append(fileIDs, b.FileID)
		}
		var files []TabFileInfo
		if len(fileIDs) > 0 {
			models.DB.Where("id IN ?", fileIDs).Find(&files)
		}

		// 查询状态变更记录
		var commits []TabPurchaseCommit
		models.DB.Where("order_id = ?", from.ID).Order("created_at DESC").Find(&commits)

		// 解析每条 commit 的 Photos JSON 字段为数组
		type CommitResponse struct {
			ID        uint      `json:"id"`
			OrderID   uint      `json:"orderId"`
			UserID    uint      `json:"userId"`
			Action    string    `json:"action"`
			Status    string    `json:"status"`
			OldStatus string    `json:"oldStatus"`
			Comment   string    `json:"comment"`
			IP        string    `json:"ip"`
			CreatedAt time.Time `json:"createdAt"`
			Photos    []string  `json:"photos"`
		}
		var commitResps []CommitResponse
		for _, c := range commits {
			// Status 优先用数据库字段；若为空（历史旧数据），从 Comment 备注中截取状态
			status := c.Status
			if status == "" {
				status = strings.TrimPrefix(c.Comment, "状态变更为: ")
				status = strings.TrimPrefix(status, "变更状态为: ")
				// 如果截取后跟原文一样，说明不是"状态变更为"格式，取原文作为展示
				if status == c.Comment {
					status = ""
				}
			}
			resp := CommitResponse{
				ID:        c.ID,
				OrderID:   c.OrderID,
				UserID:    c.UserID,
				Action:    c.Action,
				Status:    status,
				OldStatus: c.OldStatus,
				Comment:   c.Comment,
				IP:        c.IP,
				CreatedAt: time.Time{},
			}
			if c.CreatedAt != nil {
				resp.CreatedAt = *c.CreatedAt
			}
			if c.Photos != "" {
				json.Unmarshal([]byte(c.Photos), &resp.Photos)
			}
			commitResps = append(commitResps, resp)
		}

		// 查询关联工单（通过 TabWorkOrderPurchaseOrderBind 表）
		type WorkOrderInfo struct {
			ID            uint   `json:"id"`
			Title         string `json:"title"`
			CurrentStatus string `json:"status"`
		}
		var linkedWorkOrders []WorkOrderInfo
		var woBinds []TabWorkOrderPurchaseOrderBind
		models.DB.Where("purchase_order_id = ?", from.ID).Find(&woBinds)
		if len(woBinds) > 0 {
			woIDSet := make(map[uint]bool)
			var woIDs []uint
			for _, wb := range woBinds {
				if !woIDSet[wb.WorkOrderID] {
					woIDSet[wb.WorkOrderID] = true
					woIDs = append(woIDs, wb.WorkOrderID)
				}
			}
			var workOrders []TabWorkOrder
			models.DB.Where("id IN ?", woIDs).Find(&workOrders)
			for _, wo := range workOrders {
				linkedWorkOrders = append(linkedWorkOrders, WorkOrderInfo{
					ID:            wo.ID,
					Title:         wo.Title,
					CurrentStatus: wo.CurrentStatus,
				})
			}
		}
		if linkedWorkOrders == nil {
			linkedWorkOrders = []WorkOrderInfo{}
		}

		// 判断当前用户是否可以修改
		canModify := canModifyPurchase(user.ID, order.UserID)

		ReturnJson(ctx, "apiOK", gin.H{
			"order":      order,
			"canModify":  canModify,
			"costs":      costs,
			"photos":     files,
			"commits":    commitResps,
			"workOrders": linkedWorkOrders,
		})
	})

	// 更新订单状态（可附带评论）
	r.POST("/updatestatus", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userCookieError", nil)
			return
		}

		type FromUpdateStatus struct {
			ID      uint     `json:"id"`
			Status  string   `json:"status" binding:"required"`
			Comment string   `json:"comment"`
			Photos  []string `json:"photos"` // 变更附带的图片哈希
		}
		var from FromUpdateStatus
		if err := decodeJSON(data, &from); err != nil || from.ID == 0 {
			ReturnJson(ctx, "jsonErr", nil)
			return
		}

		// 校验图片哈希（不包含标点符号的哈希值）
		for _, hash := range from.Photos {
			if models.IsContainsSpecialChar(hash) {
				ReturnJson(ctx, "photo_hash_invalid", nil)
				return
			}
		}

		// 校验状态值
		validStatuses := map[string]bool{
			"pending":  true,
			"ordered":  true,
			"arrived":  true,
			"received": true,
			"lost":     true,
			"returned": true,
		}
		if !validStatuses[from.Status] {
			ReturnJson(ctx, "invalid_status", nil)
			return
		}

		var order TabPurchaseOrder
		if err := models.DB.Where("id = ?", from.ID).First(&order).Error; err != nil {
			ReturnJson(ctx, "order_not_found", nil)
			return
		}

		oldStatus := order.OrderStatus

		// 更新状态
		updates := map[string]interface{}{
			"order_status": from.Status,
		}
		if err := models.DB.Model(&order).Updates(updates).Error; err != nil {
			ReturnJson(ctx, "apiErr", nil)
			return
		}

		// 写状态变更 commit
		comment := from.Comment
		if comment == "" && len(from.Photos) == 0 {
			comment = "状态变更为: " + from.Status
		}
		photosJSON := ""
		if len(from.Photos) > 0 {
			if pj, err := json.Marshal(from.Photos); err == nil {
				photosJSON = string(pj)
			}
		}
		commit := TabPurchaseCommit{
			OrderID:   order.ID,
			UserID:    user.ID,
			Action:    "create_status",
			Status:    from.Status,
			OldStatus: oldStatus,
			Comment:   comment,
			Photos:    photosJSON,
			IP:        ctx.ClientIP(),
		}
		models.DB.Create(&commit)

		// 写操作日志
		newContent, _ := json.Marshal(map[string]string{
			"status":  from.Status,
			"comment": comment,
		})
		oldContent, _ := json.Marshal(map[string]string{
			"status": oldStatus,
		})
		tosqllog := TabPurchaseLog{
			UserID:     user.ID,
			OrderID:    order.ID,
			ActionType: "update_status",
			NewContent: string(newContent),
			OldContent: string(oldContent),
			IP:         ctx.ClientIP(),
			Remark:     comment,
		}
		models.DB.Create(&tosqllog)

		ReturnJson(ctx, "apiOK", nil)
	})

	// 删除状态记录
	r.POST("/delete_commit", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userCookieError", nil)
			return
		}

		type FromDeleteCommit struct {
			OrderID  uint `json:"orderId"`
			CommitID uint `json:"commitId"`
		}
		var from FromDeleteCommit
		if err := decodeJSON(data, &from); err != nil || from.OrderID == 0 || from.CommitID == 0 {
			ReturnJson(ctx, "jsonErr", nil)
			return
		}

		// 获取订单信息
		var order TabPurchaseOrder
		if err := models.DB.Where("id = ?", from.OrderID).First(&order).Error; err != nil {
			ReturnJson(ctx, "order_not_found", nil)
			return
		}

		// 获取进度信息
		var commit TabPurchaseCommit
		if err := models.DB.Where("id = ? AND order_id = ?", from.CommitID, from.OrderID).First(&commit).Error; err != nil {
			ReturnJson(ctx, "commit_not_found", nil)
			return
		}

		// 权限判断：订单创建者 或 进度创建者 或 管理员
		isOrderCreator := user.ID == order.UserID
		isCommitCreator := user.ID == commit.UserID
		isAdmin := slices.Contains(purchaseAdmins, user.ID)

		if !isOrderCreator && !isCommitCreator && !isAdmin {
			ReturnJson(ctx, "no_permission", nil)
			return
		}

		// 删除进度
		models.DB.Where("id = ?", from.CommitID).Delete(&TabPurchaseCommit{})

		ReturnJson(ctx, "apiOK", nil)
	})

	r.POST("/getorders", func(ctx *gin.Context) {
		isAuth, _, data := AuthenticationAuthority(ctx)
		if isAuth {
			//fmt.Println(user)
			// DebugPrintJson(data)

			type From_purchase_getorders struct {
				Search  string
				Status  string
				Entries int
				Page    int
			}

			var jsondata From_purchase_getorders
			if err := decodeJSON(data, &jsondata); err == nil {
				//fmt.Println(jsondata)

				is_data_ok := true

				if jsondata.Entries <= 0 || jsondata.Entries > 300 {
					is_data_ok = false
				}
				if jsondata.Page <= 0 {
					is_data_ok = false
				}

				if is_data_ok {

					//读取有多少条目
					var count int64
					query := models.DB.Model(TabPurchaseOrder{})
					if jsondata.Search != "" {
						// 精确匹配订单 ID
						var id uint
						if _, err := parsefmt.Sscanf(jsondata.Search, "%d", &id); err == nil && id > 0 {
							query = query.Where("id = ?", id)
						} else {
							// 模糊匹配标题和用途（Remark）
							query = query.Where("title LIKE ? OR remark LIKE ?",
								"%"+jsondata.Search+"%", "%"+jsondata.Search+"%")
						}
					}
					if jsondata.Status != "" {
						query = query.Where("order_status = ?", jsondata.Status)
					}
					query.Count(&count)

					//读取条目
					var getorders []TabPurchaseOrder
					query.Order("id DESC").Offset(jsondata.Entries * (jsondata.Page - 1)).Limit(jsondata.Entries).Find(&getorders)

					ReturnJson(ctx, "apiOK", map[string]interface{}{
						"all_count":  count,
						"all_orders": getorders,
					})

				} else {
					ReturnJson(ctx, "jsonErr_1", nil)
				}

			} else {
				ReturnJson(ctx, "jsonErr", nil)
			}

		} else {
			ReturnJson(ctx, "userCookieError", nil)
		}
	})

	r.POST("/addorder", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if isAuth {

			//需要处理提交的数据，接口有固定的数据格式，不允许乱搞
			//fmt.Println(isAuth)
			//fmt.Println(user)
			//DebugPrintJson(data)
			var jsondata From_purchase_addorder
			//fmt.Println(data)
			if err := decodeJSON(data, &jsondata); err == nil {

				//jsonStr, _ := json.MarshalIndent(jsondata, "", "  ")
				//fmt.Println("转换后数据:\n", string(jsonStr))

				//数据比较混乱 在这里校验

				//判断标题不为空
				is_data_ok := true
				if jsondata.Title == "" {
					is_data_ok = false
				}

				//判断数量与价格是否为负数
				for i := 0; i < len(jsondata.Costs); i++ {
					if jsondata.Costs[i].Cost <= 0 {
						is_data_ok = false
					}
					if jsondata.Costs[i].Int <= 0 {
						is_data_ok = false
					}
				}

				//判断图片是否为哈希值
				for i := 0; i < len(jsondata.Photos); i++ {
					//判断字符串是否包含标点符号
					if models.IsContainsSpecialChar(jsondata.Photos[i]) {
						is_data_ok = false
						//fmt.Println("err4")
					}

				}

				//判断时间字符串是否合法
				// uptime, e := models.StringToTimePtr(jsondata.UpdateTime)
				// if e != nil {
				// 	is_data_ok = false
				// 	fmt.Println("err5")
				// }

				if is_data_ok {
					//校验通过
					//photos, _ := json.Marshal(jsondata.Photos)
					new_data := TabPurchaseOrder{
						UserID:      user.ID,
						Title:       jsondata.Title,
						Remark:      jsondata.Remark,
						Link:        jsondata.Link,
						Styles:      jsondata.Styles,
						OrderStatus: "pending", // 默认待处理
					}
					models.DB.Create(&new_data)

					for i := 0; i < len(jsondata.Costs); i++ {
						currencyType := jsondata.Costs[i].CurrencyType
						if currencyType <= 0 {
							currencyType = 1 // 默认 CNY
						}
						costType := jsondata.Costs[i].Type
						if costType <= 0 {
							costType = 1 // 默认单价
						}
						new_cost_data := TabPurchaseCosts{
							Price:        jsondata.Costs[i].Cost,
							Quantity:     jsondata.Costs[i].Int,
							UserID:       user.ID,
							OrderID:      new_data.ID,
							CurrencyType: currencyType,
							CostType:     costType,
						}
						models.DB.Create(&new_cost_data)
					}

					//绑定文件
					for i := 0; i < len(jsondata.Photos); i++ {
						findFile := TabFileInfo{
							Sha256: jsondata.Photos[i],
							Type:   "image",
						}
						if models.DB.Where(&findFile).First(&findFile).Error == nil {
							bind := TabPurchaseFileBind{
								OrderID: new_data.ID,
								FileID:  findFile.ID,
							}
							models.DB.Create(&bind)
						}
					}

					// 写创建日志
					newContent, _ := json.Marshal(jsondata)
					tosqllog := TabPurchaseLog{
						UserID:     user.ID,
						OrderID:    new_data.ID,
						ActionType: "create",
						NewContent: string(newContent),
						OldContent: "",
						IP:         ctx.ClientIP(),
					}
					models.DB.Create(&tosqllog)

					// 写状态创建 commit
					commitLog := TabPurchaseCommit{
						OrderID:   new_data.ID,
						UserID:    user.ID,
						Action:    "create",
						Status:    "pending",
						OldStatus: "",
						Comment:   "订单创建",
						IP:        ctx.ClientIP(),
					}
					models.DB.Create(&commitLog)

					ReturnJson(ctx, "apiOK", nil)

				} else {
					ReturnJson(ctx, "jsonErr_1", nil)
				}

			} else {
				ReturnJson(ctx, "jsonErr", nil)
			}

		} else {
			ReturnJson(ctx, "userCookieError", nil)
		}

		//ReturnJson(ctx, "apiErr", nil)
	})

	// 编辑订单基本信息
	r.POST("/updateorder", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userCookieError", nil)
			return
		}

		type FromUpdateOrder struct {
			ID     uint       `json:"id"`
			Title  string     `json:"title"`
			Remark string     `json:"remark"`
			Link   string     `json:"link"`
			Styles string     `json:"styles"`
			Photos []string   `json:"photos"`
			Costs  []CostItem `json:"costs"`
		}
		var from FromUpdateOrder
		if err := decodeJSON(data, &from); err != nil || from.ID == 0 {
			ReturnJson(ctx, "jsonErr", nil)
			return
		}
		if from.Title == "" {
			ReturnJson(ctx, "jsonErr_1", nil)
			return
		}

		// 校验图片哈希
		for _, hash := range from.Photos {
			if models.IsContainsSpecialChar(hash) {
				ReturnJson(ctx, "photo_hash_invalid", nil)
				return
			}
		}
		// 校验费用
		for _, c := range from.Costs {
			if c.Cost <= 0 || c.Int <= 0 {
				ReturnJson(ctx, "jsonErr_1", nil)
				return
			}
		}

		var order TabPurchaseOrder
		if err := models.DB.Where("id = ?", from.ID).First(&order).Error; err != nil {
			ReturnJson(ctx, "order_not_found", nil)
			return
		}

		// 权限校验：只有创建者或管理员可以修改
		if !canModifyPurchase(user.ID, order.UserID) {
			ReturnJson(ctx, "no_permission", nil)
			return
		}

		// 记录旧数据
		oldContent, _ := json.Marshal(order)

		// 更新基本字段
		if err := models.DB.Model(&order).Updates(map[string]interface{}{
			"title":  from.Title,
			"remark": from.Remark,
			"link":   from.Link,
			"styles": from.Styles,
		}).Error; err != nil {
			ReturnJson(ctx, "apiErr", nil)
			return
		}

		// 重建费用明细：先删旧，再插新
		models.DB.Where("order_id = ?", from.ID).Delete(&TabPurchaseCosts{})
		for _, c := range from.Costs {
			ct := c.CurrencyType
			if ct <= 0 {
				ct = 1
			}
			ctype := c.Type
			if ctype <= 0 {
				ctype = 1
			}
			models.DB.Create(&TabPurchaseCosts{
				Price:        c.Cost,
				Quantity:     c.Int,
				UserID:       user.ID,
				OrderID:      from.ID,
				CurrencyType: ct,
				CostType:     ctype,
			})
		}

		// 重建图片绑定：先删旧，再插新
		models.DB.Where("order_id = ?", from.ID).Delete(&TabPurchaseFileBind{})
		for _, hash := range from.Photos {
			findFile := TabFileInfo{Sha256: hash, Type: "image"}
			if models.DB.Where(&findFile).First(&findFile).Error == nil {
				models.DB.Create(&TabPurchaseFileBind{
					OrderID: from.ID,
					FileID:  findFile.ID,
				})
			}
		}

		// 写操作日志
		newContent, _ := json.Marshal(from)
		models.DB.Create(&TabPurchaseLog{
			UserID:     user.ID,
			OrderID:    from.ID,
			ActionType: "update",
			OldContent: string(oldContent),
			NewContent: string(newContent),
			IP:         ctx.ClientIP(),
		})

		ReturnJson(ctx, "apiOK", nil)
	})

	// 删除订单
	r.POST("/deleteorder", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userCookieError", nil)
			return
		}

		type FromDeleteOrder struct {
			ID uint `json:"id"`
		}
		var from FromDeleteOrder
		if err := decodeJSON(data, &from); err != nil || from.ID == 0 {
			ReturnJson(ctx, "jsonErr", nil)
			return
		}

		var order TabPurchaseOrder
		if err := models.DB.Where("id = ?", from.ID).First(&order).Error; err != nil {
			ReturnJson(ctx, "order_not_found", nil)
			return
		}

		// 权限校验：只有创建者或管理员可以删除
		if !canModifyPurchase(user.ID, order.UserID) {
			ReturnJson(ctx, "no_permission", nil)
			return
		}

		// 关联删除（硬删，不保留）
		models.DB.Where("order_id = ?", from.ID).Delete(&TabPurchaseCosts{})
		models.DB.Where("order_id = ?", from.ID).Delete(&TabPurchaseFileBind{})
		models.DB.Where("order_id = ?", from.ID).Delete(&TabPurchaseCommit{})
		models.DB.Where("order_id = ?", from.ID).Delete(&TabPurchaseLog{})

		// 软删除订单本身
		models.DB.Delete(&order)

		ReturnJson(ctx, "apiOK", nil)
	})

	// 获取订单数量统计
	r.POST("/getordercount", func(ctx *gin.Context) {
		isAuth, _, _ := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userCookieError", nil)
			return
		}

		type OrderCount struct {
			Pending  int64 `json:"pending"`  // 待处理
			Ordered  int64 `json:"ordered"`  // 已下单
			Arrived  int64 `json:"arrived"`  // 已到达
			Received int64 `json:"received"` // 已收件
			Lost     int64 `json:"lost"`     // 丢件
			Returned int64 `json:"returned"` // 退件
			Total    int64 `json:"total"`    // 总数
		}

		var count OrderCount
		models.DB.Model(&TabPurchaseOrder{}).Count(&count.Total)
		models.DB.Model(&TabPurchaseOrder{}).Where("order_status = ?", "pending").Count(&count.Pending)
		models.DB.Model(&TabPurchaseOrder{}).Where("order_status = ?", "ordered").Count(&count.Ordered)
		models.DB.Model(&TabPurchaseOrder{}).Where("order_status = ?", "arrived").Count(&count.Arrived)
		models.DB.Model(&TabPurchaseOrder{}).Where("order_status = ?", "received").Count(&count.Received)
		models.DB.Model(&TabPurchaseOrder{}).Where("order_status = ?", "lost").Count(&count.Lost)
		models.DB.Model(&TabPurchaseOrder{}).Where("order_status = ?", "returned").Count(&count.Returned)

		ReturnJson(ctx, "apiOK", map[string]interface{}{
			"pending":  count.Pending,
			"ordered":  count.Ordered,
			"arrived":  count.Arrived,
			"received": count.Received,
			"lost":     count.Lost,
			"returned": count.Returned,
			"total":    count.Total,
		})
	})

	// 搜索工单（用于采购订单关联）
	r.POST("/search_work_orders", func(ctx *gin.Context) {
		isAuth, _, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userCookieError", nil)
			return
		}

		type FromSearch struct {
			Search string `json:"search"`
			Limit  int    `json:"limit"`
		}
		var from FromSearch
		if err := decodeJSON(data, &from); err != nil {
			ReturnJson(ctx, "jsonErr", nil)
			return
		}
		if from.Limit <= 0 || from.Limit > 20 {
			from.Limit = 5
		}

		query := models.DB.Model(&TabWorkOrder{})
		if from.Search != "" {
			var id uint
			if _, err := parsefmt.Sscanf(from.Search, "%d", &id); err == nil && id > 0 {
				query = query.Where("id = ?", id)
			} else {
				query = query.Where("title LIKE ? OR description LIKE ?",
					"%"+from.Search+"%", "%"+from.Search+"%")
			}
		}

		var orders []TabWorkOrder
		query.Order("id DESC").Limit(from.Limit).Find(&orders)

		type WorkOrderInfo struct {
			ID     uint   `json:"id"`
			Title  string `json:"title"`
			Status string `json:"status"`
		}
		var result []WorkOrderInfo
		for _, o := range orders {
			result = append(result, WorkOrderInfo{
				ID:     o.ID,
				Title:  o.Title,
				Status: o.CurrentStatus,
			})
		}
		if result == nil {
			result = []WorkOrderInfo{}
		}

		ReturnJson(ctx, "apiOK", gin.H{"orders": result})
	})

}
