package excel

import (
	"encoding/json"
	"eta/eta_api/controllers"
	"eta/eta_api/models"
	excelModel "eta/eta_api/models/data_manage/excel"
	"eta/eta_api/models/data_manage/excel/request"
	"eta/eta_api/models/data_manage/excel/response"
	"eta/eta_api/services"
	"eta/eta_api/services/data/data_manage_permission"
	"eta/eta_api/services/data/excel"
	"eta/eta_api/utils"
	"strconv"
	"strings"
	"time"
)

// CustomAnalysisController 自定义分析
type CustomAnalysisController struct {
	controllers.BaseAuthController
}

// ExcelByName
// @Title 根据excel名称获取表格详情（基础信息+第一页初始化数据）
// @Description 根据excel名称获取表格详情（基础信息+第一页初始化数据）
// @Param   ExcelName   query   string  true       "搜索关键词"
// @Success 200 {object} response.ExcelListResp
// @router /excel_by_name [get]
func (c *CustomAnalysisController) ExcelByName() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()
	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	excelName := c.GetString("ExcelName")
	if excelName == `` {
		br.Msg = "请选择表格"
		br.ErrMsg = "ExcelName未传"
		br.IsSendEmail = false
		return
	}

	resp := response.FindExcelInfoResp{}

	excelName = utils.TrimLRStr(excelName)
	// 获取数据详情
	excelDetail, err := excelModel.GetNoContentExcelInfoByName(excelName, utils.CUSTOM_ANALYSIS_TABLE)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Ret = 200
			br.Success = true
			br.Msg = "获取成功"
			br.Data = resp
			return
		}
		br.Msg = "获取表格事变"
		br.ErrMsg = err.Error()
		return
	}

	// 数据权限
	haveOperaAuth, err := data_manage_permission.CheckExcelPermissionByExcelInfoId(excelDetail.ExcelInfoId, excelDetail.ExcelClassifyId, excelDetail.IsJoinPermission, c.SysUser.AdminId)
	if err != nil {
		br.Msg = "获取ETA表格失败"
		br.ErrMsg = "获取ETA表格权限失败,Err:" + err.Error()
		return
	}

	resp.IsFind = true
	resp.ExcelInfo = response.FindExcelInfo{
		ExcelInfoId:     excelDetail.ExcelInfoId,
		Source:          excelDetail.Source,
		ExcelType:       excelDetail.ExcelType,
		ExcelName:       excelDetail.ExcelName,
		UniqueCode:      excelDetail.UniqueCode,
		ExcelClassifyId: excelDetail.ExcelClassifyId,
		SysUserId:       excelDetail.SysUserId,
		SysUserRealName: excelDetail.SysUserRealName,
		ExcelImage:      excelDetail.ExcelImage,
		FileUrl:         excelDetail.FileUrl,
		Sort:            excelDetail.Sort,
		ModifyTime:      excelDetail.ModifyTime,
		CreateTime:      excelDetail.CreateTime,
		Button:          excel.GetExcelInfoOpButton(sysUser, excelDetail.SysUserId, excelDetail.Source, haveOperaAuth),
		HaveOperaAuth:   true,
	}

	if excelDetail != nil {
		sheetList, err := excelModel.GetAllSheetItemList(excelDetail.ExcelInfoId)
		if err != nil {
			br.Msg = "获取sheet失败"
			br.ErrMsg = "获取sheet失败，err:" + err.Error()
			return
		}

		resp.SheetList = sheetList
	}

	//resp := response.ExcelListResp{
	//	Paging: page,
	//	List:   list,
	//}

	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// Add
// @Title 新增表格接口
// @Description 新增表格接口
// @Param	request	body request.AddExcelInfoReq true "type json string"
// @Success 200 {object} response.AddExcelInfoResp
// @router /add [post]
func (c *CustomAnalysisController) Add() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	deleteCache := true
	cacheKey := "CACHE_EXCEL_TABLE_INFO_ADD_" + strconv.Itoa(sysUser.AdminId)
	defer func() {
		if deleteCache {
			_ = utils.Rc.Delete(cacheKey)
		}
	}()
	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
		deleteCache = false
		br.Msg = "系统处理中，请稍后重试！"
		br.ErrMsg = "系统处理中，请稍后重试！" + sysUser.RealName + ";data:" + string(c.Ctx.Input.RequestBody)
		return
	}
	var req request.AddExcelInfoReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	req.ExcelName = strings.Trim(req.ExcelName, " ")
	if req.ExcelName == "" {
		br.Msg = "请填写表格名称！"
		br.IsSendEmail = false
		return
	}

	// 获取是否存在该表格名称
	{
		var condition string
		var pars []interface{}
		condition += " AND source=? "
		pars = append(pars, utils.CUSTOM_ANALYSIS_TABLE)

		condition += " AND excel_name=? "
		pars = append(pars, req.ExcelName)

		count, err := excelModel.GetExcelInfoCountByCondition(condition, pars)
		if err != nil {
			br.Msg = "判断表格名称是否存在失败"
			br.ErrMsg = "判断表格名称是否存在失败,Err:" + err.Error()
			return
		}
		if count > 0 {
			br.Msg = "表格名称已存在，请重新填写表格名称"
			br.IsSendEmail = false
			return
		}
	}

	if req.ExcelClassifyId <= 0 {
		br.Msg = "分类参数错误！"
		br.IsSendEmail = false
		return
	}

	excelInfo, err, errMsg, isSendEmail := excel.AddCustomAnalysisTable(utils.TrimLRStr(req.ExcelName), req.Content, req.ExcelImage, req.ExcelClassifyId, sysUser)
	if err != nil {
		br.Msg = "保存失败"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = "保存失败，Err:" + err.Error()
		br.IsSendEmail = isSendEmail
		return
	}

	// 更新excel下载地址(默认的EXCEL需要更新，自定义表格不需要更新）
	//if req.Source == 1 {
	//	go UpdateExcelInfoFileUrl(excelInfo)
	//}
	//
	resp := new(response.AddExcelInfoResp)
	resp.ExcelInfoId = excelInfo.ExcelInfoId
	resp.UniqueCode = excelInfo.UniqueCode

	// 生成excel文件
	go excel.UpdateExcelInfoFileUrl(excelInfo)

	//新增操作日志
	//{
	//	excelLog := &data_manage.ExcelInfoLog{
	//		//ExcelInfoLogId:  0,
	//		ExcelInfoId:     excelInfo.ExcelInfoId,
	//		ExcelName:       req.ExcelName,
	//		ExcelClassifyId: req.ExcelClassifyId,
	//		SysUserId:       sysUser.AdminId,
	//		SysUserRealName: sysUser.RealName,
	//		UniqueCode:      excelInfo.UniqueCode,
	//		CreateTime:      time.Now(),
	//		Content:         string(c.Ctx.Input.RequestBody),
	//		Status:          "新增表格",
	//		Method:          c.Ctx.Input.URI(),
	//	}
	//	go data_manage.AddExcelInfoLog(excelLog)
	//}

	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = false //数据量太大了，不写入日志吧
}

// Save
// @Title 保存表格接口
// @Description 保存表格接口
// @Param	request	body request.AddExcelInfoReq true "type json string"
// @Success 200 {object} response.AddExcelInfoResp
// @router /save [post]
func (c *CustomAnalysisController) Save() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	deleteCache := true
	cacheKey := "CACHE_EXCEL_TABLE_INFO_ADD_" + strconv.Itoa(sysUser.AdminId)
	defer func() {
		if deleteCache {
			_ = utils.Rc.Delete(cacheKey)
		}
	}()
	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
		deleteCache = false
		br.Msg = "系统处理中，请稍后重试！"
		br.ErrMsg = "系统处理中，请稍后重试！" + sysUser.RealName + ";data:" + string(c.Ctx.Input.RequestBody)
		return
	}
	var req request.SaveExcelInfoReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	req.ExcelName = strings.Trim(req.ExcelName, " ")
	if req.ExcelName == "" {
		br.Msg = "请填写表格名称！"
		br.IsSendEmail = false
		return
	}

	if req.ExcelInfoId <= 0 {
		br.Msg = "请选择excel！"
		br.IsSendEmail = false
		return
	}

	if req.ExcelClassifyId <= 0 {
		br.Msg = "分类参数错误！"
		br.IsSendEmail = false
		return
	}

	excelInfo, err := excelModel.GetExcelInfoById(req.ExcelInfoId)
	if err != nil {
		br.Msg = "找不到该EXCEL！"
		br.ErrMsg = "找不到该EXCEL！err:" + err.Error()
		return
	}

	if excelInfo.Source != utils.CUSTOM_ANALYSIS_TABLE {
		br.Msg = "EXCEL异常！"
		br.IsSendEmail = false
		return
	}

	err, errMsg, isSendEmail := excel.SaveCustomAnalysisTable(excelInfo, utils.TrimLRStr(req.ExcelName), req.Content, req.ExcelImage, req.ExcelClassifyId, req.OpSheetList)
	if err != nil {
		br.Msg = "保存失败"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = "保存失败，Err:" + err.Error()
		br.IsSendEmail = isSendEmail
		return
	}

	// 更新excel下载地址(默认的EXCEL需要更新，自定义表格不需要更新）
	//if req.Source == 1 {
	//	go UpdateExcelInfoFileUrl(excelInfo)
	//}
	//
	resp := new(response.AddExcelInfoResp)
	resp.ExcelInfoId = excelInfo.ExcelInfoId
	resp.UniqueCode = excelInfo.UniqueCode

	// 生成excel文件
	go excel.UpdateExcelInfoFileUrl(excelInfo)

	//新增操作日志
	//{
	//	excelLog := &data_manage.ExcelInfoLog{
	//		//ExcelInfoLogId:  0,
	//		ExcelInfoId:     excelInfo.ExcelInfoId,
	//		ExcelName:       req.ExcelName,
	//		ExcelClassifyId: req.ExcelClassifyId,
	//		SysUserId:       sysUser.AdminId,
	//		SysUserRealName: sysUser.RealName,
	//		UniqueCode:      excelInfo.UniqueCode,
	//		CreateTime:      time.Now(),
	//		Content:         string(c.Ctx.Input.RequestBody),
	//		Status:          "新增表格",
	//		Method:          c.Ctx.Input.URI(),
	//	}
	//	go data_manage.AddExcelInfoLog(excelLog)
	//}

	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = false //数据量太大了，不写入日志吧
}

// BaseExcelDetail
// @Title 根据excel名称获取表格详情（基础信息+第一页初始化数据）
// @Description 根据excel名称获取表格详情（基础信息+第一页初始化数据）
// @Param   UniqueCode   query   string  true       "excel唯一编码"
// @Success 200 {object} response.ExcelListResp
// @router /excel/base [get]
func (c *CustomAnalysisController) BaseExcelDetail() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()
	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	uniqueCode := c.GetString("UniqueCode")
	if uniqueCode == `` {
		br.Msg = "请选择表格"
		br.ErrMsg = "UniqueCode未传"
		br.IsSendEmail = false
		return
	}

	resp := response.FindExcelInfoResp{}

	// 获取数据详情
	excelDetail, err := excelModel.GetNoContentExcelInfoByUniqueCode(uniqueCode)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Ret = 200
			br.Success = true
			br.Msg = "获取成功"
			br.Data = resp
			return
		}
		br.Msg = "获取表格事变"
		br.ErrMsg = err.Error()
		return
	}
	// 编辑状态
	markStatus, err := services.UpdateExcelEditMark(excelDetail.ExcelInfoId, sysUser.AdminId, 2, sysUser.RealName)
	if err != nil {
		br.Msg = "查询标记状态失败"
		br.ErrMsg = "查询标记状态失败，Err:" + err.Error()
		return
	}

	// 数据权限
	haveOperaAuth, err := data_manage_permission.CheckExcelPermissionByExcelInfoId(excelDetail.ExcelInfoId, excelDetail.ExcelClassifyId, excelDetail.IsJoinPermission, c.SysUser.AdminId)
	if err != nil {
		br.Msg = "获取ETA表格失败"
		br.ErrMsg = "获取ETA表格权限失败,Err:" + err.Error()
		return
	}

	resp.IsFind = true
	resp.ExcelInfo = response.FindExcelInfo{
		ExcelInfoId:     excelDetail.ExcelInfoId,
		Source:          excelDetail.Source,
		ExcelType:       excelDetail.ExcelType,
		ExcelName:       excelDetail.ExcelName,
		UniqueCode:      excelDetail.UniqueCode,
		ExcelClassifyId: excelDetail.ExcelClassifyId,
		SysUserId:       excelDetail.SysUserId,
		SysUserRealName: excelDetail.SysUserRealName,
		ExcelImage:      excelDetail.ExcelImage,
		FileUrl:         excelDetail.FileUrl,
		Sort:            excelDetail.Sort,
		ModifyTime:      excelDetail.ModifyTime,
		CreateTime:      excelDetail.CreateTime,
		Button:          excel.GetExcelInfoOpButton(sysUser, excelDetail.SysUserId, excelDetail.Source, haveOperaAuth),
		HaveOperaAuth:   true,
	}
	if markStatus.Status == 0 {
		resp.ExcelInfo.CanEdit = true
	} else {
		resp.ExcelInfo.Editor = markStatus.Editor
	}
	if excelDetail != nil {
		sheetList, err := excelModel.GetAllSheetItemList(excelDetail.ExcelInfoId)
		if err != nil {
			br.Msg = "获取sheet失败"
			br.ErrMsg = "获取sheet失败，err:" + err.Error()
			return
		}

		if len(sheetList) > 0 {
			sheetIdList := make([]int, 0)
			for _, v := range sheetList {
				sheetIdList = append(sheetIdList, v.ExcelSheetId)
			}
			// 获取所有sheet的第一页的数据
			sheetDataList, err := excelModel.GetSheetDataListBySheetIdListAndPage(sheetIdList, 1)
			if err != nil {
				br.Msg = "获取sheet中的数据失败"
				br.ErrMsg = "获取sheet中的数据失败，err:" + err.Error()
				return
			}

			sheetDataMap := make(map[int]*excelModel.ExcelSheetData)
			for _, v := range sheetDataList {
				sheetDataMap[v.ExcelSheetId] = v
			}

			for k, v := range sheetList {
				sheetData, ok := sheetDataMap[v.ExcelSheetId]
				if !ok {
					continue
				}
				v.Data = sheetData
				sheetList[k] = v
			}

		}

		// TODO 合并单元格信息、计算公式

		resp.SheetList = sheetList
	}

	//resp := response.ExcelListResp{
	//	Paging: page,
	//	List:   list,
	//}

	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// ExcelDataList
// @Title 根据excel名称获取表格详情（基础信息+第一页初始化数据）
// @Description 根据excel名称获取表格详情（基础信息+第一页初始化数据）
// @Param   UniqueCode   query   string  true       "excel唯一编码"
// @Param   Page   query   int  true       "页码"
// @Success 200 {object} response.ExcelListResp
// @router /excel/data [get]
func (c *CustomAnalysisController) ExcelDataList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()
	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	uniqueCode := c.GetString("UniqueCode")
	if uniqueCode == `` {
		br.Msg = "请选择表格"
		br.ErrMsg = "UniqueCode未传"
		br.IsSendEmail = false
		return
	}

	page, _ := c.GetInt("Page")
	if page <= 0 {
		br.Msg = "页码异常"
		br.ErrMsg = "页码异常"
		br.IsSendEmail = false
		return
	}

	sheetList := make([]*excelModel.SheetItem, 0)
	// 获取数据详情
	excelDetail, err := excelModel.GetNoContentExcelInfoByUniqueCode(uniqueCode)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Ret = 200
			br.Success = true
			br.Msg = "获取成功"
			br.Data = sheetList
			return
		}
		br.Msg = "获取表格事变"
		br.ErrMsg = err.Error()
		return
	}

	if excelDetail.Source != utils.CUSTOM_ANALYSIS_TABLE {
		br.Msg = "excel异常"
		br.ErrMsg = "excel异常"
		br.IsSendEmail = false
		return
	}

	if excelDetail != nil {
		sheetList, err = excelModel.GetAllNoConfigSheetItemList(excelDetail.ExcelInfoId)
		if err != nil {
			br.Msg = "获取sheet失败"
			br.ErrMsg = "获取sheet失败，err:" + err.Error()
			return
		}

		if len(sheetList) > 0 {
			sheetIdList := make([]int, 0)
			for _, v := range sheetList {
				sheetIdList = append(sheetIdList, v.ExcelSheetId)
			}
			// 获取所有sheet的第一页的数据
			sheetDataList, err := excelModel.GetSheetDataListBySheetIdListAndPage(sheetIdList, page)
			if err != nil {
				br.Msg = "获取sheet中的数据失败"
				br.ErrMsg = "获取sheet中的数据失败，err:" + err.Error()
				return
			}

			sheetDataMap := make(map[int]*excelModel.ExcelSheetData)
			for _, v := range sheetDataList {
				sheetDataMap[v.ExcelSheetId] = v
			}

			for k, v := range sheetList {
				sheetData, ok := sheetDataMap[v.ExcelSheetId]
				if !ok {
					continue
				}
				v.Data = sheetData
				sheetList[k] = v
			}

		}

		// TODO 合并单元格信息、计算公式

	}

	//resp := response.ExcelListResp{
	//	Paging: page,
	//	List:   list,
	//}

	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = sheetList
}
