package excel

import (
	"errors"
	"eta/eta_api/models/data_manage"
	excelModel "eta/eta_api/models/data_manage/excel"
	"eta/eta_api/models/system"
	"eta/eta_api/services"
	"eta/eta_api/services/alarm_msg"
	"eta/eta_api/services/data/data_manage_permission"
	excel "eta/eta_api/services/excel"
	"eta/eta_api/utils"
	"fmt"
	"os"
	"strconv"
	"time"
)

// Delete excel删除
func Delete(excelInfo *excelModel.ExcelInfo, sysUser *system.Admin) (err error, errMsg string, isSendEmail bool) {
	isSendEmail = true

	// 操作权限校验
	{
		// 数据权限
		haveOperaAuth, tmpErr := data_manage_permission.CheckExcelPermissionByExcelInfoId(excelInfo.ExcelInfoId, excelInfo.ExcelClassifyId, excelInfo.IsJoinPermission, sysUser.AdminId)
		if err != nil {
			errMsg = "获取ETA表格权限失败"
			err = errors.New("获取ETA表格权限失败,Err:" + tmpErr.Error())
			return
		}

		button := GetExcelInfoOpButton(sysUser, excelInfo.SysUserId, excelInfo.Source, haveOperaAuth)
		if !button.DeleteButton {
			errMsg = "无操作权限"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}
	}

	// 自定义分析,需要做这个指标关联的校验
	if excelInfo.Source == utils.CUSTOM_ANALYSIS_TABLE {
		list, tmpErr := excelModel.GetExcelEdbMappingByExcelInfoId(excelInfo.ExcelInfoId)
		if tmpErr != nil {
			errMsg = `获取关联的指标信息失败`
			err = tmpErr
			return
		}

		if len(list) > 0 {
			errMsg = "已关联指标,不可删除!"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}
	} else if excelInfo.Source == utils.BALANCE_TABLE {
		// 如果父级删除是否删除子表和静态表,同时删除图表和图表数据
		excelIds := make([]int, 0)
		//查询动态表所有的子表,并复制为静态表
		condition := " AND source=?"
		var pars []interface{}
		pars = append(pars, utils.BALANCE_TABLE)
		excelIds = append(excelIds, excelInfo.ExcelInfoId)
		if excelInfo.ParentId == 0 {
			if excelInfo.BalanceType == 0 {
				condition += "  AND (parent_id = ? or rel_excel_info_id=?)"
				pars = append(pars, excelInfo.ExcelInfoId, excelInfo.ExcelInfoId)
			} else if excelInfo.BalanceType == 1 {
				condition += " AND (parent_id = ?)"
				pars = append(pars, excelInfo.ExcelInfoId)
			}
			excelList, e := excelModel.GetNoContentExcelInfoListByConditionNoPage(condition, pars)
			if e != nil {
				err = fmt.Errorf("获取子表失败 %s", err.Error())
				errMsg = "获取子表失败"
				return
			}
			for _, v := range excelList {
				excelIds = append(excelIds, v.ExcelInfoId)
			}
		}

		// 相关联指标
		mappingListTmp, e := excelModel.GetExcelChartEdbMappingByExcelInfoIds(excelIds)
		if e != nil {
			errMsg = "获取失败"
			err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", e.Error())
			return
		}

		charInfoIds := make([]int, 0)
		for _, v := range mappingListTmp {
			charInfoIds = append(charInfoIds, v.ChartInfoId)
		}
		err = excelModel.DeleteExcelChartEdbAndData(excelIds, charInfoIds)
		if err != nil {
			errMsg = "删除表格失败"
			err = fmt.Errorf("删除图表,指标信息失败 Err:%s", err.Error())
			return
		}
		_ = data_manage.DeleteEdbRelationByObjectIds(excelIds, utils.EDB_RELATION_TABLE)
		return
	}

	// 标记删除
	excelInfo.IsDelete = 1
	excelInfo.ModifyTime = time.Now()
	err = excelInfo.Update([]string{"IsDelete", "ModifyTime"})

	// 删除指标引用
	_ = data_manage.DeleteEdbRelationByObjectIds([]int{excelInfo.ExcelInfoId}, utils.EDB_RELATION_TABLE)
	return
}

// Copy 复制excel
func Copy(oldExcelInfo *excelModel.ExcelInfo, excelClassifyId int, excelName string, sysUser *system.Admin) (excelInfo *excelModel.ExcelInfo, err error, errMsg string, isSendEmail bool) {
	isSendEmail = true

	excelName = utils.TrimLRStr(excelName)

	excelClassify, err := excelModel.GetExcelClassifyById(excelClassifyId)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			errMsg = "分类不存在"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}
		errMsg = "获取分类信息失败"
		return
	}
	if excelClassify == nil {
		errMsg = "分类不存在"
		err = errors.New(errMsg)
		isSendEmail = false
		return
	}

	// 操作权限校验
	{
		// 数据权限
		haveOperaAuth, tmpErr := data_manage_permission.CheckExcelPermissionByExcelInfoId(oldExcelInfo.ExcelInfoId, oldExcelInfo.ExcelClassifyId, oldExcelInfo.IsJoinPermission, sysUser.AdminId)
		if err != nil {
			errMsg = "获取ETA表格权限失败"
			err = errors.New("获取ETA表格权限失败,Err:" + tmpErr.Error())
			return
		}

		button := GetExcelInfoOpButton(sysUser, oldExcelInfo.SysUserId, oldExcelInfo.Source, haveOperaAuth)
		if !button.CopyButton {
			errMsg = "无操作权限"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}
	}

	// 检验分类下是否存在该表格名称
	{
		var condition string
		var pars []interface{}
		condition += " AND excel_classify_id=? "
		pars = append(pars, excelClassifyId)

		condition += " AND excel_name=? "
		pars = append(pars, excelName)

		count, tmpErr := excelModel.GetExcelInfoCountByCondition(condition, pars)
		if tmpErr != nil {
			errMsg = "判断表格名称是否存在失败"
			err = tmpErr
			return
		}
		if count > 0 {
			errMsg = "表格名称已存在,请重新填写表格名称"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}
	}

	// 表格信息
	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
	excelInfo = &excelModel.ExcelInfo{
		//ExcelInfoId:     0,
		ExcelName:       excelName,
		Source:          oldExcelInfo.Source,
		ExcelType:       oldExcelInfo.ExcelType,
		UniqueCode:      utils.MD5(utils.EXCEL_DATA_PREFIX + "_" + timestamp),
		ExcelClassifyId: excelClassifyId,
		SysUserId:       sysUser.AdminId,
		SysUserRealName: sysUser.RealName,
		Content:         oldExcelInfo.Content,
		ExcelImage:      oldExcelInfo.ExcelImage,
		FileUrl:         oldExcelInfo.FileUrl,
		Sort:            0,
		IsDelete:        0,
		ModifyTime:      time.Now(),
		CreateTime:      time.Now(),
	}

	// 如果不是自定义分析,那么直接加主表就好了
	if excelInfo.Source != utils.CUSTOM_ANALYSIS_TABLE {

		// 获取excel与指标的关系表
		list, tmpErr := excelModel.GetAllExcelEdbMappingByExcelInfoId(excelInfo.ExcelInfoId)
		if tmpErr != nil {
			errMsg = "获取失败"
			err = tmpErr
			return
		}
		for k, v := range list {
			v.ExcelEdbMappingId = 0
			v.ExcelInfoId = 0
			list[k] = v
		}
		var childExcel *excelModel.ExcelInfo
		err = excelModel.AddExcelInfo(excelInfo, list, childExcel)
		if err != nil {
			errMsg = "保存失败"
		}

		return
	}

	// 自定义分析,需要有额外信息
	addSheetList := make([]excelModel.AddExcelSheetParams, 0)

	// 获取所有的sheet页
	oldSheetItemList, err := excelModel.GetAllSheetList(oldExcelInfo.ExcelInfoId)
	if err != nil {
		errMsg = `获取sheet页失败`
		return
	}

	// 获取所有的sheet页的sheet数据
	sheetCellDataMapList := make(map[int][]*excelModel.ExcelSheetData)
	{
		dataList, tmpErr := excelModel.GetAllSheetDataListByExcelInfoId(oldExcelInfo.ExcelInfoId)
		if tmpErr != nil {
			errMsg = `获取sheet页的单元格数据失败`
			err = tmpErr
			return
		}

		for _, cellData := range dataList {
			sheetDataList, ok := sheetCellDataMapList[cellData.ExcelSheetId]
			if !ok {
				sheetDataList = make([]*excelModel.ExcelSheetData, 0)
			}
			sheetCellDataMapList[cellData.ExcelSheetId] = append(sheetDataList, cellData)
		}
	}

	// sheet处理
	for _, sheetInfo := range oldSheetItemList {
		addSheetItem := excelModel.AddExcelSheetParams{
			ExcelSheetId: 0,
			ExcelInfoId:  0,
			SheetName:    sheetInfo.SheetName,
			Sort:         sheetInfo.Sort,
			Config:       sheetInfo.Config,
			CalcChain:    sheetInfo.CalcChain,
		}

		sheetDataList, ok := sheetCellDataMapList[sheetInfo.ExcelSheetId]
		if ok {
			for i, sheetData := range sheetDataList {
				sheetData.ExcelDataId = 0
				sheetData.ExcelSheetId = 0
				sheetData.ExcelInfoId = 0
				sheetDataList[i] = sheetData
			}
		}

		addSheetItem.DataList = sheetDataList

		addSheetList = append(addSheetList, addSheetItem)
	}

	// 添加表格
	err = excelModel.AddExcelInfoAndSheet(excelInfo, addSheetList)

	return
}

// UpdateExcelInfoFileUrl 更新excel表格的下载地址
func UpdateExcelInfoFileUrl(excelInfo *excelModel.ExcelInfo) {
	var err error
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg(fmt.Sprintf("更新excel表格的下载地址失败,表格id:%d;表格名称:%s; ERR:%s", excelInfo.ExcelInfoId, excelInfo.ExcelName, err), 3)
			utils.FileLog.Info(fmt.Sprintf("更新excel表格的下载地址失败,表格id:%d;表格名称:%s; ERR:%s", excelInfo.ExcelInfoId, excelInfo.ExcelName, err), 3)
		}
	}()
	fileName := excelInfo.ExcelName + "_" + excelInfo.UniqueCode + ".xlsx"

	var downloadFilePath string // excel文件下载地址

	switch excelInfo.Source {
	case utils.EXCEL_DEFAULT: // 自定义表格
		luckySheetData, tmpErr := excel.GetLuckySheetData(excelInfo.Content)
		if tmpErr != nil {
			err = tmpErr
			fmt.Println("err:", err)
			return
		}
		//_, err = luckySheetData.GetTableDataByLuckySheetDataStr()
		downloadFilePath, err = luckySheetData.ToExcel()
	case utils.CUSTOM_ANALYSIS_TABLE: // 自定义分析表格
		downloadFilePath, err, _ = GenerateExcelCustomAnalysisExcel(excelInfo)
	}

	if err != nil {
		fmt.Println("err:", err)
		return
	}
	defer func() {
		_ = os.Remove(downloadFilePath)
	}()

	var resourceUrl string
	//上传到阿里云
	//if utils.ObjectStorageClient == "minio" {
	//	resourceUrl, err = services.UploadImgToMinIo(fileName, downloadFilePath)
	//} else {
	//	resourceUrl, err = services.UploadAliyunV2(fileName, downloadFilePath)
	//}
	//if err != nil {
	//	return
	//}
	ossClient := services.NewOssClient()
	if ossClient == nil {
		err = fmt.Errorf("初始化OSS服务失败")
		return
	}
	resourceUrl, err = ossClient.UploadFile(fileName, downloadFilePath, "")
	if err != nil {
		err = fmt.Errorf("文件上传失败, Err: %s", err.Error())
		return
	}

	excelInfo.FileUrl = resourceUrl
	err = excelInfo.Update([]string{"FileUrl"})
}