package db

import (
	"fmt"
	"olympus/oncall/backend/model"
	"olympus/oncall/backend/pkg/log"
	"strconv"
)

// Get the overview of this week's schedule.
func GetCurrentOverview() (*map[string]*model.OverviewEle, string, string, error) {
	tmpWeekId, err := GetTempWeekId()
	if err != nil {
		return nil, "", "", err
	}
	const GET_OVERVIEW = `
		select
			concat(c2.category_name, ' - ', c1.category_name) as category_name,
			engineer_name,
			if(
				engineer_en_name is null,
				"",
				concat ("(", engineer_en_name, ")")
			) as engineer_en_name,
			offset,
			offset2,
			c1.remark as remark
		from
			categories as c1
			left join categories as c2 on c1.parent_category_id = c2.category_id,
			shift,
			engineers,
			t_week_id
		where
			c1.category_id = shift.category_id
			and shift.engineer_id = engineers.engineer_id
			and shift.week_id = ?
			and t_week_id.id = shift.week_id
			and c1.enable = 1
			and c1.visibility = 1`

	type Overview struct {
		CategoryName   string `gorm:"column:category_name"`
		EngineerName   string `gorm:"column:engineer_name"`
		EngineerEnName string `gorm:"column:engineer_en_name"`
		Offset         string `gorm:"column:offset"`
		Offset2        string `gorm:"column:offset2"`
		Remark         string `gorm:"column:remark"`
	}
	var startDate string
	var endDate string
	overviewArr := make([]Overview, 0)
	tmpDecimal2, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", tmpWeekId), 64)
	res := GetDB().Raw(GET_OVERVIEW, tmpDecimal2).Scan(&overviewArr)
	if res.Error != nil {
		log.Error("msg", "error: get overview", "error info", res.Error)
	}
	overviewMap := make(map[string]*model.OverviewEle)
	for _, v := range overviewArr {
		if _, exist := overviewMap[v.CategoryName]; exist {
			overviewMap[v.CategoryName].Persons = append(overviewMap[v.CategoryName].Persons, v.EngineerName+v.EngineerEnName)
		} else {
			overviewMap[v.CategoryName] = &model.OverviewEle{Persons: make([]string, 0), Description: v.Remark}
			overviewMap[v.CategoryName].Persons = append(overviewMap[v.CategoryName].Persons, v.EngineerName+v.EngineerEnName)
		}
		startDate = v.Offset
		endDate = v.Offset2
	}
	return &overviewMap, startDate, endDate, nil
}

// Get the shift view list and group by categories,
// storing in a map.
func GetShiftList() (model.TShiftList, error) {
	tmpWeekId, err := GetTempWeekId()
	if err != nil {
		return nil, err
	}
	fromWeekId := tmpWeekId - 4
	toWeekId := tmpWeekId + 8
	const GET_SHIFTVIEW = `
		SELECT
			concat(c1.category_name, ' - ', c2.category_name) as category_name,
			shift.engineer_id as engineer_id,
			engineer_name,
			if(
				engineer_en_name is null,
				"",
				concat ("(", engineer_en_name, ")")
			) as engineer_en_name,
			team_name,
			week_id,
			shift.category_id as category_id,
			offset,
			offset2
		FROM
			categories AS c1,
			categories AS c2,
			shift,
			engineers,
			teams,
			t_week_id
		WHERE
			c1.category_id = c2.parent_category_id
			AND c2.category_id = shift.category_id
			AND shift.engineer_id = engineers.engineer_id
			AND engineers.team_id = teams.team_id
			AND week_id BETWEEN ?
			AND ?
			AND week_id = t_week_id.id
			AND c1.visibility = 1
		ORDER BY
			week_id,
			engineer_name`

	shiftViewRes := make([]ShiftViewList, 0)
	fromDecimal2, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", fromWeekId), 64)
	toDecimal2, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", toWeekId), 64)
	res := GetDB().Raw(GET_SHIFTVIEW, fromDecimal2, toDecimal2).Scan(&shiftViewRes)
	if res.Error != nil {
		log.Error("msg", "error: get overview", "error info", res.Error)
	}

	shiftMap := make(model.TShiftList)
	for _, v := range shiftViewRes {
		if _, exist := shiftMap[v.CategoryName]; exist {
			shiftMap[v.CategoryName] = append(shiftMap[v.CategoryName], &model.EWPair{EngineerId: v.EngineerId, Name: v.EngineerName, EnName: v.EngineerEnName, Team: v.TeamName, WeekId: v.WeekId, CategoryId: v.CategoryId, Week: v.Offset + " - " + v.Offset2, OnDuty: v.WeekId == tmpWeekId, Changeable: v.WeekId >= tmpWeekId})
		} else {
			shiftMap[v.CategoryName] = make([]*model.EWPair, 0)
			shiftMap[v.CategoryName] = append(shiftMap[v.CategoryName], &model.EWPair{EngineerId: v.EngineerId, Name: v.EngineerName, EnName: v.EngineerEnName, Team: v.TeamName, WeekId: v.WeekId, CategoryId: v.CategoryId, Week: v.Offset + " - " + v.Offset2, OnDuty: v.WeekId == tmpWeekId, Changeable: v.WeekId >= tmpWeekId})
		}
	}
	return shiftMap, nil
}
