package models

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

type Store struct {
	Model

	Name                  string  `json:"name"`                                 // 门店名称
	Img                   string  `json:"img"`                                  // 门面图
	Tel                   string  `json:"tel" gorm:"type:varchar(20)"`          // 电话（手机号）
	Landline              string  `json:"landline" gorm:"type:varchar(20)"`     // 固定电话
	Province              string  `json:"province" gorm:"type:varchar(100)"`    // 省
	City                  string  `json:"city" gorm:"type:varchar(100)"`        // 市
	District              string  `json:"district" gorm:"type:varchar(100)"`    // 区
	Address               string  `json:"address" gorm:"type:varchar(100)"`     // 详细地址
	Longitude             float64 `json:"longitude" gorm:"column:longitude"`    // 经度
	Latitude              float64 `json:"latitude" gorm:"column:latitude"`      // 纬度
	IsOnline              uint32  `json:"is_online"`                            // 在线
	CooperativeBusinessId uint32  `json:"cooperative_business_id" gorm:"index"` // 合作商id
	CooperativeName       string  `json:"cooperative_name"`                     // 合作商名称
	MemberService         uint32  `json:"member_service"`                       // 会员服务：1 开启 2 不开启
	SalesCommRate         float64 `json:"sales_comm_rate"`                      // 门店销售提成比例
	//GameCardGoods
	CooperativeAssistantMemberDeduct *CooperativeAssistantMemberDeduct `json:"cooperative_assistant_member_deduct" gorm:"-"`
}

func (*Store) TableName() string {
	return "store"
}

type GetCooperativeStoreReq struct {
	Name                  string `json:"name"`
	CooperativeBusinessId uint32 `json:"cooperative_business_id"` // 合作商id
	CooperativeName       string `json:"cooperative_name"`        // 合作商名称
	//SysType               uint32 `json:"sys_type"`                // 1-管理系统 2-合作商系统
	SysUid   string `json:"sys_uid"`
	Page     int    `json:"pageIndex"`
	PageSize int    `json:"pageSize"`
}

func (m *GetCooperativeStoreReq) List() ([]Store, int64, error) {
	fmt.Println("store name:", m.Name)
	stores := make([]Store, 0)

	if m.CooperativeBusinessId == 0 {
		var sysUser SysUser
		err := orm.Eloquent.Table("sys_user").Where("user_id=?", m.SysUid).Find(&sysUser).Error
		if err != nil {
			logger.Error("sys user err:", logger.Field("err", err))
			return stores, 0, err
		}
		m.CooperativeBusinessId = sysUser.CooperativeBusinessId
	}
	qs := orm.Eloquent.Table("store")
	if m.Name != "" {
		qs = qs.Where("name LIKE '%" + m.Name + "%'")
	}
	if m.CooperativeBusinessId != 0 {
		qs = qs.Where("cooperative_business_id=?", m.CooperativeBusinessId)
	}
	if m.CooperativeName != "" {
		qs = qs.Where("cooperative_name LIKE '%" + m.CooperativeName + "%'")
	}
	//if m.SysType == 2 && m.CooperativeBusinessId == 0 {
	//	logger.Error("cooperative business id err:")
	//	return stores, 0, errors.New("cooperative business id err")
	//}
	page := m.Page - 1
	if page < 0 {
		page = 0
	}
	if m.PageSize == 0 {
		m.PageSize = 10
	}
	var count int64
	err := qs.Count(&count).Error
	if err != nil {
		logger.Error("count err:", logger.Field("err", err))
		return stores, count, err
	}
	err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&stores).Error
	if err != nil && err != RecordNotFound {
		logger.Errorf("err:", logger.Field("err", err))
		return stores, count, err
	}
	stores = StoreListSetCooperativeAssistantMemberDeduct(stores)
	return stores, count, nil
}

type GetStoreReq struct {
	Name                  string `json:"name"`
	CooperativeBusinessId uint32 `json:"cooperative_business_id"` // 合作商id
	CooperativeName       string `json:"cooperative_name"`        // 合作商名称
	SysType               uint32 `json:"sys_type"`                // 1-管理系统 2-合作商系统
	SysUid                string `json:"sys_uid"`
	Page                  int    `json:"pageIndex"`
	PageSize              int    `json:"pageSize"`
}

func (m *GetStoreReq) List() ([]Store, int64, error) {
	fmt.Println("store name:", m.Name)
	stores := make([]Store, 0)

	//if m.CooperativeBusinessId == 0 {
	//	var sysUser SysUser
	//	err := orm.Eloquent.Table("sys_user").Where("user_id=?", m.SysUid).Find(&sysUser).Error
	//	if err != nil {
	//		logger.Error("sys user err:",logger.Field("err",err))
	//		return stores, 0, err
	//	}
	//	m.CooperativeBusinessId = sysUser.CooperativeBusinessId
	//}
	//qs := orm.Eloquent.Table("store").Where("member_service = ?", 1)
	qs := orm.Eloquent.Table("store")
	if m.Name != "" {
		qs = qs.Where("name LIKE '%" + m.Name + "%'")
	}
	if m.CooperativeBusinessId != 0 {
		qs = qs.Where("cooperative_business_id=?", m.CooperativeBusinessId)
	}
	if m.CooperativeName != "" {
		qs = qs.Where("cooperative_name LIKE '%" + m.CooperativeName + "%'")
	}
	if m.SysType == 2 && m.CooperativeBusinessId == 0 {
		logger.Error("cooperative business id err:")
		return stores, 0, errors.New("cooperative business id err")
	}
	page := m.Page - 1
	if page < 0 {
		page = 0
	}
	if m.PageSize == 0 {
		m.PageSize = 10
	}
	var count int64
	err := qs.Count(&count).Error
	if err != nil {
		logger.Error("count err:", logger.Field("err", err))
		return stores, count, err
	}
	err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&stores).Error
	if err != nil && err != RecordNotFound {
		logger.Errorf("err:", logger.Field("err", err))
		return stores, count, err
	}
	stores = StoreListSetCooperativeAssistantMemberDeduct(stores)
	return stores, count, nil
}

func StoreListSetCooperativeAssistantMemberDeduct(list []Store) []Store {
	ids := make([]uint32, 0, len(list))
	for i, _ := range list {
		ids = append(ids, list[i].ID)
	}

	memberDeductMap, err := GetCooperativeAssistantMemberDeductMap(ids)
	if err != nil {
		logger.Error("cooperative assistant member deduct map err:", logger.Field("err", err))
		return list
	}
	for i, _ := range list {
		v, ok := memberDeductMap[list[i].ID]
		if ok {
			list[i].CooperativeAssistantMemberDeduct = v
		}
	}
	return list
}

func (m *Store) Add() error {
	err := orm.Eloquent.Create(m).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return err
	}
	return nil
}

func (m *Store) Modify() error {
	para := m.getModifyPara()
	if len(para) > 0 {
		// 查询门店信息
		oldStoreInfo, err := GetStore(m.ID)
		if err != nil {
			logger.Errorf("GetStore err:", logger.Field("err", err))
			return err
		}

		begin := orm.Eloquent.Begin()
		err = begin.Table(m.TableName()).Unscoped().Where("id", m.ID).Updates(para).Error
		if err != nil {
			begin.Rollback()
			logger.Errorf("err:", logger.Field("err", err))
			return err
		}

		if oldStoreInfo.Name != m.Name {
			// 更新库存表
			err = begin.Table("erp_stock").Where("store_id=?", m.ID).
				Updates(map[string]interface{}{
					"store_name": m.Name,
				}).Error
			if err != nil {
				begin.Rollback()
				logger.Error("Update erp_stock err:", logger.Field("err", err))
				return err
			}

			// 更新库存详情表
			err = begin.Table("erp_stock_commodity").Where("store_id=?", m.ID).
				Updates(map[string]interface{}{
					"store_name": m.Name,
				}).Error
			if err != nil {
				begin.Rollback()
				logger.Error("Update erp_stock_commodity err:", logger.Field("err", err))
				return err
			}

			// 更新采购订单表
			err = begin.Table("erp_purchase_order").Where("store_id = ? and state NOT IN ?", m.ID,
				[]uint{ErpPurchaseOrderFinished, ErpPurchaseOrderEnd}).
				Updates(map[string]interface{}{
					"store_name": m.Name,
				}).Error
			if err != nil {
				begin.Rollback()
				logger.Error("Update erp_stock_commodity err:", logger.Field("err", err))
				return err
			}
		}

		err = begin.Commit().Error
		if err != nil {
			begin.Rollback()
			logger.Error("commit err:", logger.Field("err", err))
			return err
		}
	}
	return nil
}

func (m *Store) getModifyPara() map[string]interface{} {
	paraMap := make(map[string]interface{}, 0)
	if m.Name != "" {
		paraMap["name"] = m.Name
	}
	if m.Img != "" {
		paraMap["img"] = m.Img
	}
	if m.Tel != "" {
		paraMap["tel"] = m.Tel
	}
	if m.Province != "" {
		paraMap["province"] = m.Province
	}
	if m.City != "" {
		paraMap["city"] = m.City
	}
	if m.District != "" {
		paraMap["district"] = m.District
	}
	if m.Address != "" {
		paraMap["address"] = m.Address
	}
	if m.Longitude != 0 {
		paraMap["longitude"] = m.Longitude
	}
	if m.Latitude != 0 {
		paraMap["latitude"] = m.Latitude
	}
	if m.MemberService != 0 {
		paraMap["member_service"] = m.MemberService
	}
	if m.Landline != "" {
		paraMap["landline"] = m.Landline
	}

	paraMap["sales_comm_rate"] = m.SalesCommRate

	return paraMap
}

func (m *Store) MDel(ids []uint32) error {
	err := orm.Eloquent.Table(m.TableName()).Unscoped().Where("id in (?)", ids).Delete(m).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return err
	}
	return nil
}

func GetStore(id uint32) (*Store, error) {
	var store Store
	err := orm.Eloquent.Table("store").Where("id=?", id).Find(&store).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return &store, err
	}
	return &store, nil
}

func GetStoreIdsByCooperativeBusinessId(id uint32) ([]uint32, error) {
	ids := make([]uint32, 0)
	var stores []Store
	err := orm.Eloquent.Table("store").Where("cooperative_business_id=?", id).Find(&stores).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return ids, err
	}

	for i, _ := range stores {
		ids = append(ids, stores[i].ID)
	}

	return ids, nil
}

func GetAllStoreIdsByCooperativeBusinessId(id uint32) ([]uint32, error) {
	ids := make([]uint32, 0)
	var stores []Store
	err := orm.Eloquent.Table("store").Where("cooperative_business_id = ? and is_online = 1", id).Find(&stores).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return ids, err
	}

	for i, _ := range stores {
		ids = append(ids, stores[i].ID)
	}

	return ids, nil
}

func GetAllStoreData() (map[uint32]Store, error) {
	storeMap := make(map[uint32]Store)
	var stores []Store
	err := orm.Eloquent.Table("store").Find(&stores).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return storeMap, err
	}

	for _, store := range stores {
		storeMap[store.ID] = store
	}

	return storeMap, nil
}
