package models

import (
	"LAPP_LF_MOM_BACKEND/db"
	"LAPP_LF_MOM_BACKEND/utils"
	"xorm.io/core"
)

type PmLocation struct {
	Finr      int       `json:"pm_location-finr" xorm:"not null pk INT(4)"`
	Locaid    int       `json:"pm_location-locaid" xorm:"not null pk INT(8)"`
	Locaname  string    `json:"pm_location-locaname" xorm:"not null VARCHAR(40)"`
	LocaCust1 string    `json:"pm_location-loca_cust1" xorm:"not null VARCHAR(100)"`
	LocaCust2 string    `json:"pm_location-loca_cust2" xorm:"not null VARCHAR(100)"`
	LocaCust3 string    `json:"pm_location-loca_cust3" xorm:"not null VARCHAR(100)"`
	LocaCust4 string    `json:"pm_location-loca_cust4" xorm:"not null VARCHAR(100)"`
	Lastmodif string    `json:"pm_location-lastmodif" xorm:"not null VARCHAR(14)"`
	Lastuser  string    `json:"pm_location-lastuser" xorm:"not null VARCHAR(20)"`
	Credatuz  string    `json:"pm_location-credatuz" xorm:"not null VARCHAR(14)"`
	Valst     []PmAsset `json:"valst" xorm:"-"`
	UnValst   []PmAsset `json:"unvalst" xorm:"-"`
	Children  []PmAsset `json:"children" xorm:"-"`
}

func (t *PmLocation) TableName() string {
	return "pm_location"
}

// 清除string字段的右侧空格
func (t *PmLocation) Clipped() {
	utils.TrimStruct(t, *t)
}

//增
func (t *PmLocation) Add() error {
	e := db.Eloquent.Master()
	snr := new(Snrtab)
	snr.Finr = t.Finr
	//生成ID
	Locationid, err := snr.GetNextSnr("Locationid")
	t.Locaid = utils.ValueToInt(Locationid,0)
	_, err = e.Table("pm_location").Insert(t)
	if err != nil {
		return err
	}
	var Assetids []int
	for _, v := range t.Valst {
		Assetids = append(Assetids, v.Assetid)
	}
	if !utils.ValueIsEmpty(Assetids) {
		//批量更新
		_, err = e.Table("pm_asset").In("assetid", Assetids).Where("finr = ?", t.Finr).Update(map[string]interface{}{"locaid": t.Locaid})
		if err != nil {
			return err
		}
	}
	return nil
}

//删
func (t *PmLocation) Del() error {
	e := db.Eloquent.Master()
	_, err := e.ID(core.PK{t.Finr, t.Locaid}).Delete(&PmLocation{})
	if err != nil {
		return err
	}
	countrole := new(PmAsset)
	affw, _ := e.Table("pm_asset").Where("finr = ? and locaid = ?", t.Finr, t.Locaid).Count(countrole)
	if affw > 0 {
		//更新对应的资源定义表
		_, err = e.Table("pm_asset").Where("finr = ? and locaid = ?", t.Finr, t.Locaid).Update(map[string]interface{}{"locaid": 0})
		if err != nil {
			return err
		}
	}
	return nil
}

//改
func (t *PmLocation) Update(fileds []string) error {
	e := db.Eloquent.Master()
	_, err := e.Table("pm_location").MustCols(fileds...).Where("finr = ? and locaid = ?", t.Finr, t.Locaid).Update(t)
	if err != nil {
		return err
	}
	var Assetids []int
	for _, v := range t.Valst {
		Assetids = append(Assetids, v.Assetid)
	}
	if !utils.ValueIsEmpty(Assetids) {
		//批量更新
		_, err = e.Table("pm_asset").In("assetid", Assetids).Where("finr = ?", t.Finr).Update(map[string]interface{}{"locaid": t.Locaid})
		if err != nil {
			return err
		}
	}

	var NAssetids []int
	for _, v := range t.UnValst {
		NAssetids = append(NAssetids, v.Assetid)
	}
	if !utils.ValueIsEmpty(NAssetids) {
		//批量更新
		_, err = e.Table("pm_asset").In("assetid", NAssetids).Where("finr = ?", t.Finr).Update(map[string]interface{}{"locaid": 0})
		if err != nil {
			return err
		}
	}
	return nil
}

//查
func (t *PmLocation) SelectOne() (PmLocation, error) {
	e := db.Eloquent.Master()
	var data PmLocation
	_, err := e.ID(core.PK{t.Finr, t.Locaid}).Get(&data)
	if err != nil {
		return data, err
	}
	var valst []PmAsset
	err = e.Table("pm_asset").Where("finr = ? and locaid = ?", t.Finr, t.Locaid).Find(&valst)
	if err != nil {
		return data, err
	}
	var uvalst []PmAsset
	err = e.Table("pm_asset").Where("finr = ? and (locaid =0 or locaid = null)", t.Finr).Find(&uvalst)
	if err != nil {
		return data, err
	}
	data.Valst = valst
	data.UnValst = uvalst
	return data, nil
}

//查所有
func (t *PmLocation) SelectAll() ([]PmAsset, error) {
	e := db.Eloquent.Master()
	var data []PmAsset
	err := e.Table("pm_asset").Where("finr = ? and (locaid =0 or locaid = null)", t.Finr).Find(&data)
	if err != nil {
		return data, err
	}
	return data, nil
}

//查所有地点
func (t *PmLocation) SelectLocalions() (data []PmLocation,err error) {
	e := db.Eloquent.Master()
	err = e.Table(t.TableName()).Where("finr = ?", t.Finr).Find(&data)
	if err != nil {
		return data, err
	}
	return data, nil
}

//分页
func (t *PmLocation) GetPage(descr string, pageSize int, pageIndex int) ([]PmLocation, int, error) {
	data := make([]PmLocation, 0)
	e := db.Eloquent.Master()
	table := e.Table("pm_location").Where("finr = ? ", t.Finr)
	parameters := make([]interface{}, 0)
	where := ""
	parameters = append(parameters, t.Finr)
	if descr != "" {
		table = table.And("locaname like concat('%',?,'%')", descr)
		where += " and locaname like concat('%',?,'%')"
		parameters = append(parameters, descr)
	}
	parameters = append(parameters, (pageIndex-1)*pageSize, pageSize)
	err := e.SQL("SELECT * FROM (SELECT * FROM pm_location where finr = ?"+where+") t order by locaid offset ? row fetch next ? row only", parameters...).Find(&data)
	if err != nil {
		return data, 0, err
	}

	count, err := table.Count(new(PmLocation))
	if err != nil {
		return data, 0, err
	}
	for k, _ := range data {
		data[k].Clipped()
	}
	return data, int(count), nil
}

type TreePmLocation struct {
	Locaid   int       `json:"pm_asset-locaid" xorm:"not null pk INT(8)"`
	Locaname string    `json:"pm_asset-assetname" xorm:"not null VARCHAR(40)"`
	Children []PmAsset `json:"children" xorm:"-"`
}

type LocationAsset struct {
	PmAsset    `xorm:"extends"`
	PmLocation `xorm:"extends"`
}

/**
*填充资产树：根节点为工厂，第一层节点为location；第二层节点为资产
**************/
func (t *PmLocation) TreeAsset() ([]TreePmLocation, error) {
	m := make([]TreePmLocation, 0)
	data := make([]LocationAsset, 0)
	e := db.Eloquent.Master()
	err := e.Table("pm_location").Join("left", "pm_asset", "pm_asset.finr=pm_location.finr and pm_asset.locaid=pm_location.locaid").Where("pm_location.finr = ? ", t.Finr).Find(&data)
	if err != nil {
		return m, err
	}
	tem := make(map[int]interface{})
	for i := 0; i < len(data); i++ {
		key := data[i].PmLocation.Locaid
		if utils.ValueIsEmpty(key) {
			continue
		}
		_, ok := tem[key]
		if ok {
			continue
		} else {
			tem[key] = data[i].PmLocation
		}
		val := TreePmLocation{}
		val.Locaid = data[i].PmLocation.Locaid
		val.Locaname = data[i].PmLocation.Locaname
		menusInfo := DiguiLocation(&data, val)

		m = append(m, menusInfo)
	}
	return m, nil
}

func DiguiLocation(locationlist *[]LocationAsset, location TreePmLocation) TreePmLocation {
	list := *locationlist

	min := make([]PmAsset, 0)
	for j := 0; j < len(list); j++ {
		if location.Locaid != list[j].PmLocation.Locaid {
			continue
		}
		mi := PmAsset{}
		mi.Locaid = list[j].PmAsset.Locaid
		mi.Finr = list[j].PmAsset.Finr
		mi.Descr = list[j].PmAsset.Descr
		mi.Assetid = list[j].PmAsset.Assetid
		mi.Assetname = list[j].PmAsset.Descr
		mi.Assetstatus = list[j].PmAsset.Assetstatus
		mi.Assettype = list[j].PmAsset.Assettype
		mi.Weekmodelid = list[j].PmAsset.Weekmodelid
		mi.Operator = list[j].PmAsset.Operator
		mi.Costcenterid = list[j].PmAsset.Costcenterid
		mi.Maker = list[j].PmAsset.Maker
		mi.Year = list[j].PmAsset.Year
		min = append(min, mi)
	}
	location.Children = min
	return location
}
