package implments

import (
	"LAPP_LF_MOM_BACKEND/dao/pdc"
	"LAPP_LF_MOM_BACKEND/db"
	"LAPP_LF_MOM_BACKEND/global"
	"LAPP_LF_MOM_BACKEND/grmi"
	"LAPP_LF_MOM_BACKEND/infra/logger"
	model "LAPP_LF_MOM_BACKEND/models/api"
	baseModel "LAPP_LF_MOM_BACKEND/models/base"
	"LAPP_LF_MOM_BACKEND/web/models"
	"encoding/json"
	"errors"
	"strconv"
)

/******************************************************************************
 *
 * @Struct Name              : ScrewServiceImplement
 *-----------------------------------------------------------------------------
 *
 * @Description              : ScrewService的服务实现
 *
 * @Author                   : zhangxin
 *
 * @Date                     : 2021-05-14
 *
 ******************************************************************************/
type ScrewServiceImplement struct {
}

/******************************************************************************
 *
 * @Function Name            : NewScrewServiceImplement
 *-----------------------------------------------------------------------------
 *
 * @Description              : 创建一个ScrewServiceImplement实例
 *
 * @Return Value             : ScrewServiceImplement实例
 *
 * @Author                   : zhangxin
 *
 * @Date                     : 2021-05-14
 *
 ******************************************************************************/
func NewScrewServiceImplement() *ScrewServiceImplement {
	return &ScrewServiceImplement{}
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/api/ScrewService.Receive
 *
 ******************************************************************************/
func (impl *ScrewServiceImplement) Receive(screw *model.Screw) (err error) {
	log, _ := logger.NewLogger("MES", "API")
	recData, err := json.Marshal(*screw)
	if err != nil {
		log.Error("SCREW Receive marshal failed,error:" + err.Error())
		return err
	}
	log.Info("SCREW Receive:" + string(recData))
	conn := global.WebsocketContext.Get(screw.STN)
	if conn == nil {
		log.Error("该工位和程序未建立连接")
		return errors.New("该工位和程序未建立连接")
	}
	res := conn.Emit(baseModel.EVENT_STN_DATA, recData)
	if !res {
		log.Error("像前端发送工位数据失败")
	}

	// 全局变量初始化
	//model.ScrewGlobalArtId.Lock.Lock()
	//model.ScrewGlobalMap.Lock.Lock()
	//model.ScrewGlobalNewest.Lock.Lock()
	//defer func() {
	//	model.ScrewGlobalArtId.Lock.Unlock()
	//	model.ScrewGlobalMap.Lock.Unlock()
	//	model.ScrewGlobalNewest.Lock.Unlock()
	//}()
	//if model.ScrewGlobalArtId.Map == nil {
	//	model.ScrewGlobalArtId.Map = make(map[string]string)
	//}
	//if model.ScrewGlobalNewest.Map == nil {
	//	model.ScrewGlobalNewest.Map = make(map[string]model.ScrewWithData)
	//}
	//if model.ScrewGlobalMap.Map == nil {
	//	model.ScrewGlobalMap.Map = make(map[string]map[int]model.ScrewWithData)
	//}
	//// 给当前工作的最新screw data赋值
	//var screwWithData model.ScrewWithData
	//screwWithData.Screw = *screw
	//model.ScrewGlobalNewest.Map[screw.STN] = screwWithData
	//// 校验当前工位的零件号
	//preScrewPartNo, exist := model.ScrewGlobalArtId.Map[screw.STN]
	//if !exist {
	//	model.ScrewGlobalArtId.Map[screw.STN] = screw.PARTNO
	//	preScrewPartNo = screw.PARTNO
	//}
	//// 初始化当前工位的全局map
	//_, exist = model.ScrewGlobalMap.Map[screw.STN]
	//if !exist {
	//	model.ScrewGlobalMap.Map[screw.STN] = make(map[int]model.ScrewWithData)
	//}
	//if preScrewPartNo != screw.PARTNO {
	//	model.ScrewGlobalMap.Map[screw.STN] = make(map[int]model.ScrewWithData)
	//}
	//model.ScrewGlobalMap.Map[screw.STN][screw.SCREW_POS] = screwWithData
	//model.ScrewGlobalArtId.Map[screw.STN] = screw.PARTNO
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/api/ScrewService.GetNewestScrew
 *
 ******************************************************************************/
func (impl *ScrewServiceImplement) GetNewestScrew(user *models.Usertab, stn string) (result model.ScrewWithData, err error) {
	model.ScrewGlobalNewest.Lock.RLock()
	defer model.ScrewGlobalNewest.Lock.RUnlock()
	if model.ScrewGlobalNewest.Map == nil {
		return result, nil
		//return result, grmi.NewBusinessError("未获取到该工位的数据")
	}
	screwData, exist := model.ScrewGlobalNewest.Map[stn]
	if !exist {
		return result, nil
		//return result, grmi.NewBusinessError("未获取到该工位的数据")
	}
	if screwData.PicPath == "" {
		engine := db.Eloquent.Master()
		session := engine.NewSession()
		dao := pdc.NewScrewDownDAO(session, user.Pid, user.Userid)
		pic, err := dao.SelectOne(screwData.PARTNO, screwData.SCREW_POS, screwData.RESULT)
		if err != nil {
			return result, err
		}
		if pic == nil {
			return result, grmi.NewBusinessError("不存在对应的零件图, pos:" + strconv.Itoa(screwData.SCREW_POS) + " result: " + strconv.FormatBool(screwData.RESULT))
		}
		screwData.PicPath = pic.PicPath
		model.ScrewGlobalNewest.Map[stn] = screwData
	}
	return screwData, nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/api/ScrewService.GetScrewLi
 *
 ******************************************************************************/
func (impl *ScrewServiceImplement) GetScrewLi(user *models.Usertab, stn string) (result []model.ScrewWithData, err error) {
	result = make([]model.ScrewWithData, 0)
	model.ScrewGlobalMap.Lock.RLock()
	defer model.ScrewGlobalMap.Lock.RUnlock()
	if model.ScrewGlobalMap.Map == nil {
		//return result, grmi.NewBusinessError("未获取到该工位的数据")
		return result, nil
	}
	screwMap, exist := model.ScrewGlobalMap.Map[stn]
	if !exist {
		//return result, grmi.NewBusinessError("未获取到该工位的数据")
		return result, nil
	}
	var picPath string
	for _, screwData := range screwMap {
		if screwData.PicPath == "" {
			if picPath == "" {
				engine := db.Eloquent.Master()
				session := engine.NewSession()
				dao := pdc.NewScrewDownDAO(session, user.Pid, user.Userid)
				pic, err := dao.SelectOne(screwData.PARTNO, screwData.SCREW_POS, screwData.RESULT)
				if err != nil {
					return result, err
				}
				if pic == nil {
					return result, grmi.NewBusinessError("不存在对应的零件图, pos:" + strconv.Itoa(screwData.SCREW_POS) + " result: " + strconv.FormatBool(screwData.RESULT))
				}
				picPath = pic.PicPath
				screwData.PicPath = pic.PicPath
			} else {
				screwData.PicPath = picPath
			}
			screwMap[screwData.SCREW_POS] = screwData
		}
		if screwData.SCREW_POS != -1 {
			result = append(result, screwData)
		}
	}
	if picPath != "" {
		model.ScrewGlobalMap.Map[stn] = screwMap
	}
	for i := 0; i < len(result)-1; i++ {
		for j := 0; j < len(result)-1-i; j++ {
			if result[j].SCREW_POS > result[j+1].SCREW_POS {
				result[j+1], result[j] = result[j], result[j+1]
			}
		}
	}
	return result, nil
}
