package fe_calendar

import (
	"eta/eta_api/utils"
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"strings"
	"time"
)

const (
	MatterTypeFree    = 1 // 事项类型-自定义事项
	MatterTypeEdb     = 2 // 事项类型-基础指标
	MatterTypePredict = 3 // 事项类型-预测指标
)

// FeCalendarMatter 外汇日历-事项表
type FeCalendarMatter struct {
	FeCalendarMatterId  int       `orm:"column(fe_calendar_matter_id);pk" description:"事项ID"`
	ChartPermissionId   int       `description:"品种ID"`
	ChartPermissionName string    `description:"品种名称"`
	MatterMonth         string    `description:"事项年月:格式2006-01"`
	MatterDate          time.Time `description:"事项日期"`
	Title               string    `description:"标题"`
	MatterType          int       `description:"事项类型:1-自定义事项;2-基础指标;3-预测指标"`
	EdbInfoId           int       `description:"指标ID"`
	EdbUniqueCode       string    `description:"指标唯一编码"`
	EdbCode             string    `description:"指标编码"`
	FontColor           string    `description:"字体颜色"`
	FillingColor        string    `description:"填充颜色"`
	FontBold            int       `description:"字体加粗:0-否;1-是"`
	Sort                int       `description:"排序"`
	SysUserId           int       `description:"创建人ID"`
	SysUserName         string    `description:"创建人姓名"`
	CreateTime          time.Time `description:"创建时间"`
	ModifyTime          time.Time `description:"更新时间"`
}

var FeCalendarMatterCols = struct {
	FeCalendarMatterId  string
	ChartPermissionId   string
	ChartPermissionName string
	MatterMonth         string
	MatterDate          string
	Title               string
	MatterType          string
	EdbInfoId           string
	EdbUniqueCode       string
	EdbCode             string
	FontColor           string
	FillingColor        string
	FontBold            string
	Sort                string
	SysUserId           string
	SysUserName         string
	CreateTime          string
	ModifyTime          string
}{
	FeCalendarMatterId:  "fe_calendar_matter_id",
	ChartPermissionId:   "chart_permission_id",
	ChartPermissionName: "chart_permission_name",
	MatterMonth:         "matter_month",
	MatterDate:          "matter_date",
	Title:               "title",
	MatterType:          "matter_type",
	EdbInfoId:           "edb_info_id",
	EdbUniqueCode:       "edb_unique_code",
	EdbCode:             "edb_code",
	FontColor:           "font_color",
	FillingColor:        "filling_color",
	FontBold:            "font_bold",
	Sort:                "sort",
	SysUserId:           "sys_user_id",
	SysUserName:         "sys_user_name",
	CreateTime:          "create_time",
	ModifyTime:          "modify_time",
}

func (m *FeCalendarMatter) TableName() string {
	return "fe_calendar_matter"
}

func (m *FeCalendarMatter) PrimaryId() string {
	return FeCalendarMatterCols.FeCalendarMatterId
}

func (m *FeCalendarMatter) Create() (err error) {
	o := orm.NewOrmUsingDB("data")
	id, err := o.Insert(m)
	if err != nil {
		return
	}
	m.FeCalendarMatterId = int(id)
	return
}

func (m *FeCalendarMatter) CreateMulti(items []*FeCalendarMatter) (err error) {
	if len(items) == 0 {
		return
	}
	o := orm.NewOrmUsingDB("data")
	_, err = o.InsertMulti(len(items), items)
	return
}

func (m *FeCalendarMatter) Update(cols []string) (err error) {
	o := orm.NewOrmUsingDB("data")
	_, err = o.Update(m, cols...)
	return
}

func (m *FeCalendarMatter) Del() (err error) {
	o := orm.NewOrmUsingDB("data")
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
	_, err = o.Raw(sql, m.FeCalendarMatterId).Exec()
	return
}

func (m *FeCalendarMatter) MultiDel(menuIds []int) (err error) {
	if len(menuIds) == 0 {
		return
	}
	o := orm.NewOrmUsingDB("data")
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.PrimaryId(), utils.GetOrmInReplace(len(menuIds)))
	_, err = o.Raw(sql, menuIds).Exec()
	return
}

func (m *FeCalendarMatter) GetItemById(id int) (item *FeCalendarMatter, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
	err = o.Raw(sql, id).QueryRow(&item)
	return
}

func (m *FeCalendarMatter) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *FeCalendarMatter, err error) {
	o := orm.NewOrmUsingDB("data")
	order := ``
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order)
	err = o.Raw(sql, pars).QueryRow(&item)
	return
}

func (m *FeCalendarMatter) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
	err = o.Raw(sql, pars).QueryRow(&count)
	return
}

func (m *FeCalendarMatter) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*FeCalendarMatter, err error) {
	o := orm.NewOrmUsingDB("data")
	fields := strings.Join(fieldArr, ",")
	if len(fieldArr) == 0 {
		fields = `*`
	}
	order := fmt.Sprintf(`ORDER BY %s DESC`, FeCalendarMatterCols.CreateTime)
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
	_, err = o.Raw(sql, pars).QueryRows(&items)
	return
}

func (m *FeCalendarMatter) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*FeCalendarMatter, err error) {
	o := orm.NewOrmUsingDB("data")
	fields := strings.Join(fieldArr, ",")
	if len(fieldArr) == 0 {
		fields = `*`
	}
	order := fmt.Sprintf(`ORDER BY %s DESC`, FeCalendarMatterCols.CreateTime)
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
	return
}

type FeCalendarMatterItem struct {
	FeCalendarMatterId  int    `description:"事项ID"`
	ChartPermissionId   int    `description:"品种ID"`
	ChartPermissionName string `description:"品种名称"`
	MatterDate          string `description:"事项日期"`
	Title               string `description:"标题"`
	MatterType          int    `description:"事项类型:1-自定义事项;2-基础指标;3-预测指标"`
	EdbInfoId           int    `description:"指标ID"`
	EdbUniqueCode       string `description:"指标唯一编码"`
	EdbCode             string `description:"指标编码"`
	FontColor           string `description:"字体颜色"`
	FillingColor        string `description:"填充颜色"`
	FontBold            int    `description:"字体加粗:0-否;1-是"`
	Sort                int    `description:"排序"`
}

func FormatFeCalendarMatter2Item(origin *FeCalendarMatter) (item *FeCalendarMatterItem) {
	if origin == nil {
		return
	}
	item = new(FeCalendarMatterItem)
	item.FeCalendarMatterId = origin.FeCalendarMatterId
	item.ChartPermissionId = origin.ChartPermissionId
	item.ChartPermissionName = origin.ChartPermissionName
	item.MatterDate = utils.TimeTransferString(utils.FormatDate, origin.MatterDate)
	item.Title = origin.Title
	item.MatterType = origin.MatterType
	item.EdbInfoId = origin.EdbInfoId
	item.EdbUniqueCode = origin.EdbUniqueCode
	item.EdbCode = origin.EdbCode
	item.FontColor = origin.FontColor
	item.FillingColor = origin.FillingColor
	item.FontBold = origin.FontBold
	item.Sort = origin.Sort
	return
}

// FeCalendarMatterListReq 事项列表请求体
type FeCalendarMatterListReq struct {
	ChartPermissionId int    `form:"ChartPermissionId" description:"品种ID"`
	StartDate         string `form:"StartDate" description:"开始日期"`
	EndDate           string `form:"EndDate" description:"结束日期"`
}

// FeCalendarMatterListItem 事项列表
type FeCalendarMatterListItem struct {
	Date    string                  `description:"日期"`
	Matters []*FeCalendarMatterItem `description:"日期事项"`
}

// FeCalendarMatterSaveReq 保存事项请求体
type FeCalendarMatterSaveReq struct {
	ChartPermissionId int                         `description:"品种ID"`
	MatterDate        string                      `description:"日期"`
	Matters           []*FeCalendarMatterSaveItem `description:"事项"`
}

type FeCalendarMatterSaveItem struct {
	FeCalendarMatterId int    `description:"事项ID"`
	Title              string `description:"标题"`
	MatterType         int    `description:"事项类型:1-自定义事项;2-基础指标;3-预测指标"`
	EdbInfoId          int    `description:"指标ID"`
	EdbUniqueCode      string `description:"指标唯一编码"`
	EdbCode            string `description:"指标编码"`
	FontColor          string `description:"字体颜色"`
	FillingColor       string `description:"填充颜色"`
	FontBold           int    `description:"字体加粗:0-否;1-是"`
	Sort               int    `description:"排序"`
}

func (m *FeCalendarMatter) Save(addMatters, editMatters, removeMatters []*FeCalendarMatter, updateCols []string) (err error) {
	o := orm.NewOrmUsingDB("data")
	tx, e := o.Begin()
	if e != nil {
		err = fmt.Errorf("begin tx err: %s", e.Error())
		return
	}
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			return
		}
		_ = tx.Commit()
	}()

	if len(addMatters) > 0 {
		_, e = tx.InsertMulti(len(addMatters), addMatters)
		if e != nil {
			err = fmt.Errorf("insert multi err: %s", e.Error())
			return
		}
	}
	if len(editMatters) > 0 {
		for _, v := range editMatters {
			_, e = tx.Update(v, updateCols...)
			if e != nil {
				err = fmt.Errorf("update err: %s", e.Error())
				return
			}
		}
	}
	if len(removeMatters) > 0 {
		p, e := tx.Raw(fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())).Prepare()
		if e != nil {
			err = fmt.Errorf("remove prepare err: %s", e.Error())
			return
		}
		defer func() {
			_ = p.Close()
		}()
		for _, v := range removeMatters {
			_, e = p.Exec(v.FeCalendarMatterId)
			if e != nil {
				err = fmt.Errorf("remove exec err: %s", e.Error())
				return
			}
		}
	}
	return
}