package models

import (
	"errors"
	"fmt"
	orm "go-admin/common/global"
)

//go:generate goqueryset -in cashier.go

// ErpCashier 账号表
type ErpCashier struct {
	Model

	Name        string `json:"name" gorm:"type:varchar(512)"`         // 账号名称
	BankName    string `json:"bank_name" gorm:"type:varchar(512)"`    // 银行全称
	BankAccount string `json:"bank_account" gorm:"type:varchar(512)"` // 银行账号
	State       uint32 `json:"state"`                                 // 状态:1-使用 2-未用
	Remark      string `json:"remark" gorm:"type:varchar(512)"`       // 备注
	Type        uint32 `json:"type"`                                  //
}

type ErpStoreCashier struct {
	Model

	ErpCashierId uint32 `json:"erp_cashier_id" gorm:"index"`           // 账号id
	Name         string `json:"name" gorm:"type:varchar(512)"`         // 账号名称
	BankName     string `json:"bank_name" gorm:"type:varchar(512)"`    // 银行全称
	BankAccount  string `json:"bank_account" gorm:"type:varchar(512)"` // 银行账号
	StoreId      uint32 `json:"store_id" gorm:"index"`                 // 门店id
	StoreName    string `json:"store_name"`                            // 门店名称
	State        uint32 `json:"state"`                                 // 状态:1-使用 2-未用
	Remark       string `json:"remark" gorm:"type:varchar(512)"`       // 备注
	Type         uint32 `json:"type"`                                  //
}

// CashierStore 账号关联的门店信息
type CashierStore struct {
	StoreId   uint32 `json:"store_id" gorm:"index"` // 门店id
	StoreName string `json:"store_name"`            // 门店名称
}

// ErpCashierList 账号信息
type ErpCashierDetail struct {
	ErpCashier                // 账号表信息
	StoreList  []CashierStore `json:"store_list"` // 账号关联的门店信息
}

type ErpCashierListResp struct {
	Total     int          `json:"total"`     // 数据总条数
	PageIndex int          `json:"pageIndex"` // 页码
	PageSize  int          `json:"pageSize"`  // 每页展示条数
	List      []ErpCashier `json:"list"`
}

// CreateAccount 创建账号
func CreateAccount(req *ErpCashier, storeNums []uint32) error {
	exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_cashier WHERE `name`='%s'", req.Name))
	if err != nil {
		return fmt.Errorf("创建失败[QueryRecordExist err]：%v", err)
	}

	if exist {
		return errors.New("创建失败，账号名称重复")
	}

	// 新建账号，并绑定有效店铺
	cashier := &ErpCashier{
		Name:        req.Name,
		BankName:    req.BankName,
		BankAccount: req.BankAccount,
		Type:        1,
		State:       1,
		Remark:      "",
	}
	begin := orm.Eloquent.Begin()
	if err = begin.Create(cashier).Error; err != nil {
		return fmt.Errorf("创建失败[create cashier err]：%v", err)
	}

	var stores []Store
	err = orm.Eloquent.Table("store").Where("id IN (?)", storeNums).Find(&stores).Error
	if err != nil {
		return fmt.Errorf("创建失败[query store err]：%v", err)
	}

	storeMap := make(map[uint32]string, len(stores))
	for i, _ := range stores {
		storeMap[stores[i].ID] = stores[i].Name
	}
	for i, _ := range storeNums {
		v, ok := storeMap[storeNums[i]]

		storeCategory := &ErpStoreCashier{
			ErpCashierId: cashier.ID,
			Name:         req.Name,
			BankName:     req.BankName,
			BankAccount:  req.BankAccount,
			StoreId:      storeNums[i],
			State:        1,
			Remark:       "",
			Type:         1,
		}
		if ok {
			storeCategory.StoreName = v
		}
		err := begin.Create(storeCategory).Error
		if err != nil {
			begin.Rollback()
			return fmt.Errorf("创建失败[create store err]：%v", err)
		}
	}
	err = begin.Commit().Error
	if err != nil {
		begin.Rollback()
		return fmt.Errorf("创建失败[commit err]：%v", err)
	}

	return nil
}

// UpdateAccount 更新账号
func UpdateAccount(req *ErpCashier, storeNums []uint32) error {
	exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_cashier WHERE `id`='%d'", req.ID))
	if err != nil {
		return fmt.Errorf("更新失败[QueryRecordExist err]：%v", err)
	}
	if !exist {
		return errors.New("更新失败，账号不存在")
	}

	tx := orm.Eloquent.Begin()
	// 更新账号信息
	cashier := &ErpCashier{
		Name:        req.Name,
		BankName:    req.BankName,
		BankAccount: req.BankAccount,
		State:       1,
	}
	var cashierInfo ErpCashier
	if err := orm.Eloquent.Table("erp_cashier").Where("id=?", req.ID).Find(&cashierInfo).Error; err != nil {
		return fmt.Errorf("更新失败[update cashier err]：%v", err)
	}

	if err := tx.Model(&ErpCashier{}).Where("id=?", req.ID).Updates(cashier).Error; err != nil {
		tx.Rollback()
		return fmt.Errorf("更新失败[update cashier err]：%v", err)
	}

	// 更新账号关联的门店信息
	var stores []ErpStoreCashier
	if err := tx.Model(&ErpStoreCashier{}).Where("erp_cashier_id=?", req.ID).Find(&stores).Error; err != nil {
		tx.Rollback()
		return fmt.Errorf("更新失败[query store_cashier err]：%v", err)
	}

	matchedStoreIDs := make(map[uint32]bool) // 用于记录storeNums中已经匹配的门店ID
	for i := range stores {
		store := &stores[i]
		store.Name = req.Name
		store.BankName = req.BankName
		store.BankAccount = req.BankAccount
		store.Type = cashierInfo.Type

		if containsStore(storeNums, store.StoreId) { // 更新门店状态
			store.State = 1 // 使用
			matchedStoreIDs[store.StoreId] = true
		} else {
			store.State = 2 // 未使用
		}

		if err := tx.Model(&ErpStoreCashier{}).Where("id = ?", store.ID).Updates(store).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("更新失败[update store err]：%v", err)
		}
	}

	// 处理storeNums中存在但在数据库中不存在的门店
	for _, v := range storeNums {
		if _, exists := matchedStoreIDs[v]; !exists {
			storeInfo := &Store{}
			if err := tx.Table("store").Where("id = ?", v).First(storeInfo).Error; err != nil {
				tx.Rollback()
				return fmt.Errorf("更新失败[query store err]：%v", err)
			}
			// 新增门店数据
			newStore := ErpStoreCashier{
				StoreName:    storeInfo.Name,
				ErpCashierId: req.ID,
				StoreId:      v,
				Name:         req.Name,
				BankName:     req.BankName,
				BankAccount:  req.BankAccount,
				State:        1, // 使用
				Type:         cashierInfo.Type,
			}
			if err := tx.Create(&newStore).Error; err != nil {
				tx.Rollback()
				return fmt.Errorf("新增失败[create store err]：%v", err)
			}
		}
	}

	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		return fmt.Errorf("更新失败[commit err]：%v", err)
	}
	return nil
}

// containsStore 检查门店是否在切片中
func containsStore(storeNums []uint32, storeID uint32) bool {
	for _, v := range storeNums {
		if v == storeID {
			return true
		}
	}
	return false
}

// DeleteAccount 删除账号
func DeleteAccount(cashierId uint32) error {
	// 删除账号信息
	cashier := &ErpCashier{}
	cashier.ID = cashierId
	tx := orm.Eloquent.Begin()
	if err := orm.Eloquent.Delete(cashier).Error; err != nil {
		tx.Rollback()
		return fmt.Errorf("删除失败[create cashier err]：%v", err)
	}

	// 更新账号关联的门店信息
	var stores []ErpStoreCashier
	err := orm.Eloquent.Table("erp_store_cashier").Where("erp_cashier_id=?", cashierId).Find(&stores).Error
	if err != nil {
		return fmt.Errorf("删除失败[query store_cashier err]：%v", err)
	}

	err = orm.Eloquent.Delete(stores).Error
	if err != nil {
		tx.Rollback()
		return fmt.Errorf("删除失败[delete store err]：%v", err)
	}

	err = tx.Commit().Error
	if err != nil {
		tx.Rollback()
		return fmt.Errorf("删除失败[commit err]：%v", err)
	}

	return nil
}

// GetAccountList 查询账号列表
func GetAccountList(storeId, pageSize, pageIndex int) (*ErpCashierListResp, error) {
	resp := ErpCashierListResp{
		PageIndex: pageIndex,
		PageSize:  pageSize,
	}

	page := pageIndex - 1
	if page < 0 {
		page = 0
	}
	if pageSize == 0 {
		pageSize = 10
	}

	qs := orm.Eloquent
	if storeId == 0 { // 只查询账号信息
		qs = orm.Eloquent.Table("erp_cashier")
	} else { // 查询账号信息及其关联的门店
		qs = orm.Eloquent.Table("erp_store_cashier").Where("store_id=? and state = 1", storeId)
	}

	var count int64
	err := qs.Count(&count).Error
	if err != nil {
		return nil, fmt.Errorf("query count err:%v", err)
	}
	offset := page * pageSize
	limit := pageSize

	//resp.Total = int(count)/pageSize + 1
	var cashiers []ErpCashier

	if storeId == 0 { // 只查询账号信息
		err = qs.Order("id DESC").Offset(offset).Limit(limit).Find(&cashiers).Error
	} else { // 查询账号信息及其关联的门店
		var storeCashiers []ErpStoreCashier
		err = qs.Order("erp_cashier_id DESC").Offset(offset).Limit(limit).Find(&storeCashiers).Error
		for _, v := range storeCashiers {
			temp := ErpCashier{
				Name:        v.Name,
				BankName:    v.BankName,
				BankAccount: v.BankAccount,
				State:       v.State,
				Type:        v.Type,
			}
			temp.Model.ID = v.ErpCashierId
			cashiers = append(cashiers, temp)
		}
	}

	if err != nil && !errors.Is(err, RecordNotFound) {
		//logger.Error("erp commodity list err:", err)
		return nil, fmt.Errorf("query err:%v", err)
	}

	if storeId != 0 {
		//添加默认的账号信息
		defaultCashier, err := setDefaultCashier()
		if err != nil {
			return nil, err
		}

		for _, item := range defaultCashier {
			cashiers = append(cashiers, item)
		}
	}

	resp.List = cashiers

	//跟之前保持一致
	resp.Total = int(count)
	resp.PageIndex = page + 1
	resp.PageSize = pageSize

	return &resp, nil
}

// 添加默认的收付款账号信息
func setDefaultCashier() ([]ErpCashier, error) {
	var cashierList []ErpCashier
	err := orm.Eloquent.Table("erp_cashier").Order("id DESC").Where("id IN (1,2,3,4)").
		Find(&cashierList).Error
	if err != nil {
		return nil, err
	}

	return cashierList, nil
}

// GetAccountDetail 查询账号详情
func GetAccountDetail(cashierId int) (*ErpCashierDetail, error) {
	// 查账号信息
	var cashier ErpCashier
	err := orm.Eloquent.Table("erp_cashier").Where("id=?", cashierId).First(&cashier).Error
	if err != nil {
		return nil, fmt.Errorf("erp_cashier query err:%v", err)
	}

	// 查账号关联的门店信息
	var storeCashiers []ErpStoreCashier
	err = orm.Eloquent.Table("erp_store_cashier").
		Where("erp_cashier_id =? and state=1", cashierId).Find(&storeCashiers).Error
	if err != nil {
		return nil, fmt.Errorf("erp_store_cashier query err:%v", err)
	}

	var storeList []CashierStore
	for _, v := range storeCashiers {
		tmp := CashierStore{
			StoreId:   v.StoreId,
			StoreName: v.StoreName,
		}
		storeList = append(storeList, tmp)
	}

	resp := ErpCashierDetail{cashier, storeList}
	return &resp, nil
}
