package schedule

import (
	dal "LAPP_ACURA_MOM_BACKEND/dao/base"
	"LAPP_ACURA_MOM_BACKEND/db"
	model "LAPP_ACURA_MOM_BACKEND/models/base"
	"errors"
	"fmt"
	"time"
)

type TimeModelSrv struct {
	PlantNr       int
	StartDate     time.Time
	EndDate       time.Time
	DayModelDict  map[int]DayModelSrv  // 日模型字典
	WeekModelDict map[int]WeekModelSrv // 周模型字典
	CalendarDict  map[int]CalendarSrv  // 日历字典
	WorkShiftDict map[int]WorkShiftSrv // 人员班组字典
}

// LoadBasicData 加载日模型、周模型和工作日历等基础数据
func (tmsrv *TimeModelSrv) LoadBasicData(startDate, endDate time.Time) (err error) {
	var (
		dmsrv     DayModelSrv
		wkmsrv    WeekModelSrv
		calsrv    CalendarSrv
		wssrv     WorkShiftSrv
		dmtablst  []model.DayModel
		wkmtablst []model.WeekModel
		caltablst []model.WorkCalendar
		wstablst  []model.WorkShift
		i         int
	)
	// 初始化
	tmsrv.DayModelDict = make(map[int]DayModelSrv)
	tmsrv.WeekModelDict = make(map[int]WeekModelSrv)
	tmsrv.CalendarDict = make(map[int]CalendarSrv)
	tmsrv.WorkShiftDict = make(map[int]WorkShiftSrv)

	// 加载日模型
	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewDayModelDAO(session, tmsrv.PlantNr, "scheduler")
	if dmtablst, err = dao.SelectAll(); err != nil {
		err = errors.New(fmt.Sprintf("加载工厂%d的日模型失败%v!", tmsrv.PlantNr, err))
		return
	}
	for i = 0; i < len(dmtablst); i++ {
		dmsrv = DayModelSrv{}
		dmsrv.Init(dmtablst[i])
		tmsrv.DayModelDict[dmsrv.DayModelNr] = dmsrv
	}

	// 加载周模型
	wkmtab := dal.NewWeekModelDAO(session, tmsrv.PlantNr, "scheduler")
	if wkmtablst, err = wkmtab.SelectAll(); err != nil {
		err = errors.New(fmt.Sprintf("加载工厂%d的周模型失败%v!", tmsrv.PlantNr, err))
		return
	}
	for i = 0; i < len(wkmtablst); i++ {
		wkmsrv = WeekModelSrv{}
		wkmsrv.Init(wkmtablst[i])
		tmsrv.WeekModelDict[wkmsrv.WeekModelNr] = wkmsrv
	}

	// 加载工作日历
	caltab := dal.NewWorkCalendarDAO(session, tmsrv.PlantNr, "scheduler")
	if caltablst, err = caltab.SelectAll(startDate, endDate); err != nil {
		err = errors.New(fmt.Sprintf("加载工厂%d的工作日历失败%v!", tmsrv.PlantNr, err))
		return
	}
	for i = 0; i < len(caltablst); i++ {
		calsrv = CalendarSrv{}
		calsrv.Init(caltablst[i])
		tmsrv.CalendarDict[calsrv.CalendarNr] = calsrv
	}

	// 加载工作班次模型
	wstab := dal.NewWorkShiftDAO(session, tmsrv.PlantNr, "scheduler")
	if wstablst, err = wstab.SelectAll(); err != nil {
		err = errors.New(fmt.Sprintf("加载工厂%d的人员班组失败%v!", tmsrv.PlantNr, err))
		return
	}
	for i = 0; i < len(wstablst); i++ {
		wssrv = WorkShiftSrv{}
		wssrv.Init(wstablst[i])
		tmsrv.WorkShiftDict[wssrv.WorkShiftNr] = wssrv
	}

	return
}

// 生成日模型的可用时间线
func (tmsrv *TimeModelSrv) GenDayModelLineArray() (err error) {
	var (
		dms            DayModelSrv
		wssrv          WorkShiftSrv
		lssrv          LineSegementSrv
		nextStartPoint int
		ok             bool
	)

	// 遍历日模型
	for _, dms = range tmsrv.DayModelDict {
		dms.LineArray = []LineSegementSrv{}
		// 是否是人员班组
		if dms.DayModelTab.WorkShiftToggle {
			// 班次1
			if dms.DayModelTab.S1WorkShiftNr != 0 {
				if wssrv, ok = tmsrv.WorkShiftDict[dms.DayModelTab.S1WorkShiftNr]; !ok {
					err = errors.New(fmt.Sprintf("日模型%d的班次1对应的人员班次%d不存在！", dms.DayModelTab.DayModelNr, dms.DayModelTab.S1WorkShiftNr))
					return
				}
				nextStartPoint = wssrv.Wsstab.SBeg
				if wssrv.Wsstab.SB1Beg > 0 && wssrv.Wsstab.SB1End > wssrv.Wsstab.SB1Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB1Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB1End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB2End > 0 && wssrv.Wsstab.SB2End > wssrv.Wsstab.SB2Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB2Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB2End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB3End > 0 && wssrv.Wsstab.SB3End > wssrv.Wsstab.SB3Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB3Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB3End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB4End > 0 && wssrv.Wsstab.SB4End > wssrv.Wsstab.SB4Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB4Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB4End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB5End > 0 && wssrv.Wsstab.SB5End > wssrv.Wsstab.SB5Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB5Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB5End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				lssrv = LineSegementSrv{}
				lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
				lssrv.StartSecond = nextStartPoint
				lssrv.EndSecond = wssrv.Wsstab.SEnd
				lssrv.GetDuration()
				dms.LineArray = append(dms.LineArray, lssrv)
			}

			// 班次2
			if dms.DayModelTab.S2WorkShiftNr != 0 {
				if wssrv, ok = tmsrv.WorkShiftDict[dms.DayModelTab.S2WorkShiftNr]; !ok {
					err = errors.New(fmt.Sprintf("日模型%d的班次2对应的人员班次%d不存在！", dms.DayModelTab.DayModelNr, dms.DayModelTab.S2WorkShiftNr))
					return
				}
				nextStartPoint = wssrv.Wsstab.SBeg
				if wssrv.Wsstab.SB1Beg > 0 && wssrv.Wsstab.SB1End > wssrv.Wsstab.SB1Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB1Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB1End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB2End > 0 && wssrv.Wsstab.SB2End > wssrv.Wsstab.SB2Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB2Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB2End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB3End > 0 && wssrv.Wsstab.SB3End > wssrv.Wsstab.SB3Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB3Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB3End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB4End > 0 && wssrv.Wsstab.SB4End > wssrv.Wsstab.SB4Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB4Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB4End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB5End > 0 && wssrv.Wsstab.SB5End > wssrv.Wsstab.SB5Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB5Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB5End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				lssrv = LineSegementSrv{}
				lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
				lssrv.StartSecond = nextStartPoint
				lssrv.EndSecond = wssrv.Wsstab.SEnd
				lssrv.GetDuration()
				dms.LineArray = append(dms.LineArray, lssrv)
			}
			// 班次3
			if dms.DayModelTab.S3WorkShiftNr != 0 {
				if wssrv, ok = tmsrv.WorkShiftDict[dms.DayModelTab.S3WorkShiftNr]; !ok {
					err = errors.New(fmt.Sprintf("日模型%d的班次3对应的人员班次%d不存在！", dms.DayModelTab.DayModelNr, dms.DayModelTab.S3WorkShiftNr))
					return
				}
				nextStartPoint = wssrv.Wsstab.SBeg
				if wssrv.Wsstab.SB1Beg > 0 && wssrv.Wsstab.SB1End > wssrv.Wsstab.SB1Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB1Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB1End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB2End > 0 && wssrv.Wsstab.SB2End > wssrv.Wsstab.SB2Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB2Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB2End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB3End > 0 && wssrv.Wsstab.SB3End > wssrv.Wsstab.SB3Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB3Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB3End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB4End > 0 && wssrv.Wsstab.SB4End > wssrv.Wsstab.SB4Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB4Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB4End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if wssrv.Wsstab.SB5End > 0 && wssrv.Wsstab.SB5End > wssrv.Wsstab.SB5Beg {
					lssrv = LineSegementSrv{}
					lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = wssrv.Wsstab.SB5Beg
					lssrv.GetDuration()
					nextStartPoint = wssrv.Wsstab.SB5End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				lssrv = LineSegementSrv{}
				lssrv.WorkShiftNr = wssrv.Wsstab.WorkShiftNr
				lssrv.StartSecond = nextStartPoint
				lssrv.EndSecond = wssrv.Wsstab.SEnd
				lssrv.GetDuration()
				dms.LineArray = append(dms.LineArray, lssrv)
			}
		} else {
			// 班次1
			if dms.DayModelTab.S1Toggle {
				nextStartPoint = dms.DayModelTab.S1Beg
				if dms.DayModelTab.S1B1End > 0 && dms.DayModelTab.S1B1End > dms.DayModelTab.S1B1Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S1B1Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S1B1End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S1B2End > 0 && dms.DayModelTab.S1B2End > dms.DayModelTab.S1B2Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S1B2Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S1B2End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S1B3End > 0 && dms.DayModelTab.S1B3End > dms.DayModelTab.S1B3Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S1B3Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S1B3End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S1B4End > 0 && dms.DayModelTab.S1B4End > dms.DayModelTab.S1B4Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S1B4Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S1B4End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S1B5End > 0 && dms.DayModelTab.S1B5End > dms.DayModelTab.S1B5Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S1B5Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S1B5End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				lssrv = LineSegementSrv{}
				lssrv.StartSecond = nextStartPoint
				lssrv.EndSecond = dms.DayModelTab.S1End
				lssrv.GetDuration()
				dms.LineArray = append(dms.LineArray, lssrv)
			}

			// 班次2
			if dms.DayModelTab.S2Toggle {
				nextStartPoint = dms.DayModelTab.S2Beg
				if dms.DayModelTab.S2B1End > 0 && dms.DayModelTab.S2B1End > dms.DayModelTab.S2B1Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S2B1Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S2B1End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S2B2End > 0 && dms.DayModelTab.S2B2End > dms.DayModelTab.S2B2Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S2B2Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S2B2End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S2B3End > 0 && dms.DayModelTab.S2B3End > dms.DayModelTab.S2B3Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S2B3Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S2B3End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S2B4End > 0 && dms.DayModelTab.S2B4End > dms.DayModelTab.S2B4Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S2B4Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S2B4End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S2B5End > 0 && dms.DayModelTab.S2B5End > dms.DayModelTab.S2B5Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S2B5Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S2B5End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				lssrv = LineSegementSrv{}
				lssrv.StartSecond = nextStartPoint
				lssrv.EndSecond = dms.DayModelTab.S2End
				lssrv.GetDuration()
				dms.LineArray = append(dms.LineArray, lssrv)
			}

			// 班次2
			if dms.DayModelTab.S3Toggle {
				nextStartPoint = dms.DayModelTab.S3Beg
				if dms.DayModelTab.S3B1End > 0 && dms.DayModelTab.S3B1End > dms.DayModelTab.S3B1Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S3B1Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S3B1End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S3B2End > 0 && dms.DayModelTab.S3B2End > dms.DayModelTab.S3B2Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S3B2Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S3B2End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S3B3End > 0 && dms.DayModelTab.S3B3End > dms.DayModelTab.S3B3Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S3B3Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S3B3End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S3B4End > 0 && dms.DayModelTab.S3B4End > dms.DayModelTab.S3B4Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S3B4Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S3B4End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				if dms.DayModelTab.S3B5End > 0 && dms.DayModelTab.S3B5End > dms.DayModelTab.S3B5Beg {
					lssrv = LineSegementSrv{}
					lssrv.StartSecond = nextStartPoint
					lssrv.EndSecond = dms.DayModelTab.S3B5Beg
					lssrv.GetDuration()
					nextStartPoint = dms.DayModelTab.S3B5End
					dms.LineArray = append(dms.LineArray, lssrv)
				}
				lssrv = LineSegementSrv{}
				lssrv.StartSecond = nextStartPoint
				lssrv.EndSecond = dms.DayModelTab.S3End
				lssrv.GetDuration()
				dms.LineArray = append(dms.LineArray, lssrv)
			}
		}

		tmsrv.DayModelDict[dms.DayModelNr] = dms
	}
	return
}
