package supplier

import (
	"errors"
	"fmt"
	"fonchain-fiee/api/supplier"
	"fonchain-fiee/pkg/logic"
	"fonchain-fiee/pkg/model/login"
	"fonchain-fiee/pkg/service"
	"fonchain-fiee/pkg/service/upload"
	"fonchain-fiee/pkg/utils"
	"fonchain-fiee/pkg/utils/excel"
	"os"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/google/uuid"
)

func GetSupplier(c *gin.Context) {
	req := &supplier.GetSupplierRequest{}
	if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
		service.Error(c, err)
		return
	}
	res, err := service.SupplierProvider.GetSupplier(c, req)
	if err != nil {
		service.Error(c, err)
		return
	}

	service.Success(c, res)
	return
}
func CreateSupplier(c *gin.Context) {
	req := &supplier.CreateSupplierRequest{}
	if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
		service.Error(c, err)
		return
	}
	res, err := service.SupplierProvider.CreateSupplier(c, req)
	if err != nil {
		service.Error(c, err)
		return
	}
	service.Success(c, res)
	return
}

func UpdateSupplier(c *gin.Context) {
	req := &supplier.UpdateSupplierRequest{}
	if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
		service.Error(c, err)
		return
	}
	info, err := service.SupplierProvider.GetSupplier(c, &supplier.GetSupplierRequest{Id: req.Id})
	if err != nil {
		service.Error(c, err)
		return
	}
	if info.Status == 3 {
		service.Error(c, errors.New("审核中不可修改")) //todo 修改:审核中并且存在审核人 不可修改
		return
	}
	if req.Status != 1 && req.Status != 2 {
		service.Error(c, errors.New("审批状态错误")) //todo 只允许前端暂存或提交审核申请
	}
	res, err := service.SupplierProvider.UpdateSupplier(c, req)
	if err != nil {
		service.Error(c, err)
		return
	}
	service.Success(c, res)
	return
}

func GetSupplierList(c *gin.Context) {
	req := &supplier.GetSupplierListRequest{}
	if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
		service.Error(c, err)
		return
	}
	res, err := service.SupplierProvider.GetSupplierList(c, req)
	if err != nil {
		service.Error(c, err)
		return
	}
	service.Success(c, res)
	return
}

func CreateOrganizeDictionary(c *gin.Context) {
	req := &supplier.CreateOrganizeDictionaryRequest{}
	if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
		service.Error(c, err)
		return
	}
	res, err := service.SupplierProvider.CreateOrganizeDictionary(c, req)
	if err != nil {
		service.Error(c, err)
		return
	}
	service.Success(c, res)
	return
}

func GetOrganizeDictionaryList(c *gin.Context) {
	req := &supplier.GetOrganizeDictionaryListRequest{}
	if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
		service.Error(c, err)
		return
	}
	res, err := service.SupplierProvider.GetOrganizeDictionaryList(c, req)
	if err != nil {
		service.Error(c, err)
		return
	}
	service.Success(c, res)
	return
}

func GetCountryRegionList(c *gin.Context) {
	req := &supplier.GetCountryRegionListRequest{}
	if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
		service.Error(c, err)
		return
	}
	res, err := service.SupplierProvider.GetCountryRegionList(c, req)
	if err != nil {
		service.Error(c, err)
		return
	}
	service.Success(c, res)
	return
}

func CreateImportRecord(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		service.Error(c, err)
	}
	safeFilename := fmt.Sprintf("%d", time.Now().Unix()) + "_" + file.Filename
	userInfo := login.GetUserInfoFromC(c)
	fileDir := fmt.Sprintf("/fiee/supplier/%s/%s_%s", time.Now().Format("2006-01-02"), userInfo.Name, safeFilename)
	// 保存上传的文件到本地
	if err = c.SaveUploadedFile(file, safeFilename); err != nil {
		service.Error(c, err)
		return
	}
	defer func() {
		if err := os.Remove(safeFilename); err != nil {
			// 处理删除文件失败的情况
			fmt.Println("Failed to delete file:", err)
		}
	}()
	inputUrl, err := upload.PutBosWithName(safeFilename, false, fileDir)
	if err != nil {
		service.Error(c, err)
		return
	}
	supplierList, err := logic.ImportSupplier(safeFilename)
	if err != nil {
		service.Error(c, err)
		return
	}
	if len(supplierList) == 0 {
		service.Error(c, errors.New("导入数据为空"))
		return
	}
	uuid, _ := uuid.NewUUID()
	var SuccessNum uint64
	var SupplierCodes []string
	var ErrSupplierRes []*logic.ErrSupplierRes
	for idx, i := range supplierList {
		rowNum := idx + 1
		if i.OwningEntityName == "" || i.LegalName == "" || i.CountryOrRegionName == "" || i.CompanyRegistrationNumber == "" || i.SupplierType == "" || i.ApprovalStatus == "" || i.ConnectedParty == "" {
			ErrSupplierRes = append(ErrSupplierRes, &logic.ErrSupplierRes{
				ID:        rowNum,
				LegalName: i.LegalName,
				Remark:    "必填项存在空值",
			})
			continue
		}
		OwningEntityRes, _ := service.SupplierProvider.GetOrganizeDictionaryInfo(c, &supplier.CreateOrganizeDictionaryRequest{Name: i.OwningEntityName})
		if OwningEntityRes == nil || OwningEntityRes.Id == 0 {
			ErrSupplierRes = append(ErrSupplierRes, &logic.ErrSupplierRes{
				ID:        rowNum,
				LegalName: i.LegalName,
				Remark:    "所属组织不存在",
			})
			continue
		}
		countryRegionRes, _ := service.SupplierProvider.GetCountryRegionInfo(c, &supplier.GetCountryRegionInfoRequest{ZhAndCode: i.CountryOrRegionName})
		if countryRegionRes == nil || countryRegionRes.Id == 0 {
			ErrSupplierRes = append(ErrSupplierRes, &logic.ErrSupplierRes{
				ID:        rowNum,
				LegalName: i.LegalName,
				Remark:    "所属国家或地区不存在",
			})
			continue
		}
		var LastReviewDate string
		if i.ApprovalDate != "" {
			t, err := time.Parse("2006-01-02", i.ApprovalDate)
			if err != nil {
				LastReviewDate = ""
				i.ApprovalDate = ""
			} else {
				LastReviewDate = t.AddDate(1, 0, 0).Format("2006-01-02")
			}
		}
		createRes, err := service.SupplierProvider.CreateSupplier(c, &supplier.CreateSupplierRequest{
			OwningEntityId:                  OwningEntityRes.Id,
			LegalName:                       i.LegalName,
			LocalName:                       i.LocalName,
			AbbreviationName:                i.AbbreviationName,
			CountryOrRegionId:               countryRegionRes.Id,
			CompanyRegistrationNumber:       i.CompanyRegistrationNumber,
			SupplierType:                    i.SupplierType,
			ApprovalStatus:                  i.ApprovalStatus,
			ApprovalDate:                    i.ApprovalDate,
			LastReviewDate:                  LastReviewDate,
			LegalEntityType:                 i.LegalEntityType,
			SanctionsCountryScreeningResult: i.SanctionsCountryScreeningResult,
			KeyFinancial:                    i.KeyFinancial,
			CompanyAddress:                  i.CompanyAddress,
			PrimaryContact:                  i.PrimaryContact,
			DataOwnerDepartment:             i.DataOwnerDepartment,
			BasicCompanyInformation:         i.BasicCompanyInformation,
			SupplementaryText:               i.SupplementaryText,
			Status:                          1,
			ConnectedParty:                  i.ConnectedParty,
		})
		if err != nil {
			ErrSupplierRes = append(ErrSupplierRes, &logic.ErrSupplierRes{
				ID:        rowNum,
				LegalName: i.LegalName,
				Remark:    err.Error(),
			})
			continue
		} else {
			SupplierCodes = append(SupplierCodes, createRes.SupplierCode)
			SuccessNum++
		}

	}
	status := 2
	outUrl := ""
	if len(ErrSupplierRes) == 0 {
		status = 1
	} else {
		var sheet1Columns = []string{"行数", "供应商法定全称", "错误信息"}
		var sheet1 = excel.NewSheet("Sheet1", ErrSupplierRes, sheet1Columns)
		ex, err := excel.NewExcelCreatorFromTemplate("./mistake.xlsx", "./supplier/excel/", "", sheet1)
		ex.UseOption(excel.OptionFileNameSuffixWithUnixTime)
		path, _, err := ex.WriteToFile()
		outUrl, err = upload.PutBos(path, "", false)
		if err != nil {
			service.Error(c, err)
			return
		}
		defer func() {
			os.RemoveAll("./supplier")
		}()
	}
	req := &supplier.CreateImportRecordRequest{
		SupplierCodes: SupplierCodes,
		Status:        uint64(status),
		UserId:        userInfo.ID,
		ToLeadUrl:     inputUrl,
		DeriveUrl:     outUrl,
		Uuid:          uuid.String(),
		SuccessNum:    SuccessNum,
		FailNum:       uint64(len(ErrSupplierRes)),
	}
	_, err = service.SupplierProvider.CreateImportRecord(c, req)
	if err != nil {
		service.Error(c, err)
		return
	}
	service.Success(c, req)
	return
}

func GetImportRecordInfo(c *gin.Context) {
	req := &supplier.GetImportRecordRequest{}
	if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
		service.Error(c, err)
		return
	}
	res, err := service.SupplierProvider.GetImportRecordInfo(c, req)
	if err != nil {
		service.Error(c, err)
		return
	}
	service.Success(c, res)
	return
}

func GetExportList(c *gin.Context) {
	req := &supplier.GetSupplierListRequest{}
	if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
		service.Error(c, err)
		return
	}
	infoRes, err := service.SupplierProvider.GetSupplierList(c, req)
	if err != nil {
		service.Error(c, err)
		return
	}
	// 定义标题列表
	titleList := []string{
		"状态/State", "使用组织/Owning Entity", "供应商唯一编码/SupplierUnique Code", "供应商法定全称（英文）/LegalName (English)", "供应商本地名称（如有）/LocalName (if applicable)",
		"所在国家或地区/Country or Region", "公司注册编号/Company RegistrationNumber", "供应商类型/Supplier Type", "*是否关联方/Connected party", "准入状态/Approval Status", "准入日期/ApprovalDate",
		"法律实体形式/Legal Entity Type", "制裁与高风险国家筛查结果/Sanctions & High-RiskCountry Screening Result", "关键财务与付款信息/Key Financial & Payment Information",
		"公司地址/Company Address", "主要联系人、职位及联系方式/Primary Contact,Position&Details", "数据维护部门&人员/Data Owner Department/Personnel", "最后更新日期/Last Updated Date",
		"公司信息概要/Summary of Basic Company Information",
	}
	// 定义数据结构
	type DataInfo struct {
		Status                          string
		OwningEntity                    string
		SupplierUniqueCode              string
		LegalName                       string
		LocalName                       string
		CountryOrRegion                 string
		CompanyRegistrationNumber       string
		SupplierType                    string
		ConnectedParty                  string
		ApprovalStatus                  string
		ApprovalDate                    string
		LegalEntityType                 string
		SanctionsCountryScreeningResult string
		KeyFinancial                    string
		CompanyAddress                  string
		PrimaryContact                  string
		DataOwnerDepartment             string
		UpdatedAt                       string
		BasicCompanyInformation         string
	}
	// 创建员工ID到DataInfo的映射
	dataMap := make(map[string]*DataInfo)
	statusMap := map[uint64]string{
		1: "草稿",
		2: "审核中",
		3: "已驳回",
		4: "已成功",
	}
	for _, info := range infoRes.Data {
		dataMap[info.SupplierUniqueCode] = &DataInfo{
			Status:                          statusMap[info.Status],
			OwningEntity:                    info.OwningEntityName,
			SupplierUniqueCode:              info.SupplierUniqueCode,
			LegalName:                       info.LegalName,
			LocalName:                       info.LocalName,
			CountryOrRegion:                 info.CountryOrRegionCode,
			CompanyRegistrationNumber:       info.CompanyRegistrationNumber,
			SupplierType:                    info.SupplierType,
			ConnectedParty:                  info.ConnectedParty,
			ApprovalStatus:                  info.ApprovalStatus,
			ApprovalDate:                    info.ApprovalDate,
			LegalEntityType:                 info.LegalEntityType,
			SanctionsCountryScreeningResult: info.SanctionsCountryScreeningResult,
			KeyFinancial:                    info.KeyFinancial,
			CompanyAddress:                  info.CompanyAddress,
			PrimaryContact:                  info.PrimaryContact,
			DataOwnerDepartment:             info.DataOwnerDepartment,
			UpdatedAt:                       info.UpdatedAt,
			BasicCompanyInformation:         info.BasicCompanyInformation,
		}
	}
	// 生成最终数据列表
	var dataList []interface{}
	for _, data := range dataMap {
		dataList = append(dataList, &[]any{
			data.Status, data.OwningEntity, data.SupplierUniqueCode, data.LegalName, data.LocalName,
			data.CountryOrRegion, data.CompanyRegistrationNumber, data.SupplierType, data.ConnectedParty, data.ApprovalStatus, data.ApprovalDate,
			data.LegalEntityType, data.SanctionsCountryScreeningResult, data.KeyFinancial, data.CompanyAddress, data.PrimaryContact,
			data.DataOwnerDepartment, data.UpdatedAt, data.BasicCompanyInformation,
		})
	}

	// 生成Excel文件
	content, err := utils.ToExcelByType(titleList, dataList, "slice", "")
	if err != nil {
		service.Error(c, err)
		return
	}

	// 返回Excel文件
	utils.ResponseXls(c, content, "供应商库")
	return
}
