package statistic_report

import (
	"errors"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"github.com/shopspring/decimal"
	"hongze/hz_crm_api/models/company"
	statisticModels "hongze/hz_crm_api/models/statistic_report"
	"hongze/hz_crm_api/models/system"
	"hongze/hz_crm_api/services"
	"hongze/hz_crm_api/utils"
	"strconv"
	"strings"
	"time"
)

func CompanyList(sysUser *system.Admin, req statisticModels.IncrementalCompanyListReq) (resp CompanyListResp, err error, errMsg string) {
	pageSize := req.PageSize
	currentIndex := req.CurrentIndex
	CompanyIds := req.CompanyIds

	//排序参数
	sortParam := req.SortParam
	sortType := req.SortType

	roleTypeCode := sysUser.RoleTypeCode
	var total int
	page := paging.GetPaging(currentIndex, pageSize, total)
	//resp := new(CompanyListResp)

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = paging.StartIndex(currentIndex, pageSize)
	var condition string
	var pars []interface{}

	if CompanyIds != "" {
		fmt.Println("CompanyIds:", CompanyIds)
		condition += ` AND b.company_id IN (` + strings.Replace(CompanyIds, "\"", "", -1) + `) `
	}

	productId := services.GetProductId(roleTypeCode)
	{
		//权限控制
		//如果不是超级管理员或者财务
		if roleTypeCode != utils.ROLE_TYPE_CODE_ADMIN && roleTypeCode != utils.ROLE_TYPE_CODE_FINANCE {
			//如果是部门管理员
			condition += ` AND b.product_id=? `
			pars = append(pars, productId)
		}
	}

	total, err = company.GetCompanyListCount(condition, pars)
	if err != nil {
		errMsg = "获取数据总数失败，Err:" + err.Error()
		err = errors.New("获取失败")
		return
	}
	status := `全部`
	sortStr := ``
	if sortParam != "" && sortType != "" {
		if sortParam == "expireDay" {
			if roleTypeCode == utils.ROLE_TYPE_CODE_ADMIN {
				if sortType == "asc" {
					sortStr = " ORDER BY min_end_date"
				} else {
					sortStr = " ORDER BY max_end_date"
				}
			} else {
				sortStr = " ORDER BY b.end_date "
			}
		} else if sortParam == "createTime" {
			sortStr = " ORDER BY a.created_time "
		} else if sortParam == "viewTotal" {
			if roleTypeCode == utils.ROLE_TYPE_CODE_ADMIN {
				sortStr = " ORDER BY all_view_total"
			} else {
				sortStr = " ORDER BY b.view_total"
			}
		} else if sortParam == "viewTime" {
			if roleTypeCode == utils.ROLE_TYPE_CODE_ADMIN {
				if sortType == "asc" {
					sortStr = " ORDER BY min_last_view_time"
				} else {
					sortStr = " ORDER BY max_last_view_time"
				}
			} else {
				sortStr = " ORDER BY b.last_view_time "
			}
		} else if sortParam == "roadShowTotal" {
			sortStr = " ORDER BY b.road_show_total "
		} else if sortParam == "formalTime" {
			sortStr = " ORDER BY b.formal_time "
		} else if sortParam == "freezeTime" {
			sortStr = " ORDER BY b.freeze_time "
		} else if sortParam == "lossTime" {
			sortStr = " ORDER BY b.loss_time "
		} else if sortParam == "deadline" {
			if roleTypeCode == utils.ROLE_TYPE_CODE_ADMIN {
				sortStr = " ORDER BY sort_todo_end_time asc, all_view_total desc, a.created_time desc"
			} else {
				sortStr = " ORDER BY sort_todo_end_time asc, b.view_total desc, a.created_time desc"
			}
		} else if sortParam == "sellerName" {
			sortStr = " ORDER BY CONVERT( b.seller_name USING gbk ) COLLATE gbk_chinese_ci "
		} else if sortParam == "shareSellerName" {
			sortStr = " ORDER BY CONVERT( b.share_seller USING gbk ) COLLATE gbk_chinese_ci "
		} else if sortParam == "status" {
			sortStr = " ORDER BY sort_status "
		}  else if sortParam == "serviceYears" {
			sortStr = " ORDER BY d.first_date"
		} else if sortParam == "latestServiceRecord" {
			sortStr = " ORDER BY c.latest_service_record "
		}else {
			errMsg = "排序字段传入数据异常:" + sortParam
			err = errors.New("获取失败")
			return
		}

		if sortParam != "deadline" {
			if sortType == "asc" {
				sortStr += " ASC "
			} else if sortType == "desc" {
				sortStr += " DESC "
			} else {
				errMsg = "排序类型传入数据异常:" + sortType
				err = errors.New("获取失败")
				return
			}
		}
	} else {
		//2、客户列表选择“全部”时，支持按照“创建时间”对“全部”分类下所有客户列表进行升降序排列；选择“正式”时按照“转正时间”、选择“冻结”时按照“冻结时间”、选择“流失”时按照“流失时间”、选择“永续”时按照“创建时间”；
		if status == "全部" || status == "永续" {
			sortStr = " ORDER BY c.latest_service_record ASC"
		} else if status == "正式" {
			sortStr = " ORDER BY b.formal_time DESC"
		} else if status == "冻结" {
			sortStr = " ORDER BY b.freeze_time DESC"
		} else if status == "流失" {
			sortStr = " ORDER BY b.loss_time DESC"
		} else if status == "试用" {
			if roleTypeCode == utils.ROLE_TYPE_CODE_ADMIN {
				sortStr = " ORDER BY all_view_total DESC"
			} else {
				sortStr = " ORDER BY b.view_total DESC"
			}
		}
	}

	list, err := company.GetCompanyList(condition, status, sortStr, pars, startSize, pageSize)
	if err != nil {
		errMsg = "获取数据失败，Err:" + err.Error()
		err = errors.New("获取失败")
		return
	}

	//企业用户数组切片
	companyIdSlice := make([]string, 0)
	for _, v := range list {
		companyIdSlice = append(companyIdSlice, strconv.Itoa(v.CompanyId))
	}

	//企业用户产品开通数
	companyIdStr := strings.Join(companyIdSlice, ",")
	companyProductTotalList, _ := company.GetCountProductByCompanyIds(companyIdStr)
	companyProductTotalMap := make(map[int]*company.CompanyProductTotalSlice)
	for _, companyProductTotal := range companyProductTotalList {
		companyProductTotalMap[companyProductTotal.CompanyId] = companyProductTotal
	}
	lenList := len(list)

	// 客户产品详细信息
	companyProductMap := make(map[string]*company.CompanyProduct)
	var companyProductCondition string
	var companyProductPars []interface{}
	if productId != 0 {
		companyProductCondition += ` AND product_id=? `
		companyProductPars = append(companyProductPars, productId)
	}

	companyProductList, err := company.GetCompanyProductsByCompanyIds(companyIdStr, companyProductCondition, companyProductPars)
	if err != nil {
		errMsg = "获取客户产品数据失败，Err:" + err.Error()
		err = errors.New("获取失败")
		return
	}
	for _, companyProduct := range companyProductList {
		key := fmt.Sprint(companyProduct.CompanyId, "_", companyProduct.ProductId)
		companyProductMap[key] = companyProduct
	}

	sysUserProductId := 0

	//获取名下所有的分组
	myChildSysGroupMap := make(map[int]*system.SysGroup)
	switch sysUser.RoleTypeCode {
	case utils.ROLE_TYPE_CODE_FICC_GROUP: //ficc主管
		myChildSysGroupMap, err = services.GetBigGroupByFiccGroupId(sysUser.GroupId)
		sysUserProductId = 1
	case utils.ROLE_TYPE_CODE_FICC_TEAM: //ficc组长
		myChildSysGroupMap, err = services.GetBigGroupAllGroupInfo(sysUser.GroupId)
		sysUserProductId = 1
	case utils.ROLE_TYPE_CODE_RAI_GROUP: //权益组长
		myChildSysGroupMap, err = services.GetBigGroupAllGroupInfo(sysUser.GroupId)
		sysUserProductId = 2
	case utils.ROLE_TYPE_CODE_RAI_SELLER: //权益销售
		myChildSysGroupMap, err = services.GetBigGroupAllGroupInfo(sysUser.GroupId)
		sysUserProductId = 2
	case utils.ROLE_TYPE_CODE_FICC_SELLER: //ficc销售
		myChildSysGroupMap, err = services.GetBigGroupAllGroupInfo(sysUser.GroupId)
		sysUserProductId = 1
	}

	for i := 0; i < lenList; i++ {
		item := list[i]

		//校验该客户是否存在多个产品，如果是，那么代表是共享客户
		if companyProductTotal, ok := companyProductTotalMap[int(item.CompanyId)]; ok {
			if companyProductTotal.Total > 1 {
				list[i].IsShared = true
			}
		}

		var expireDay string
		itemStatus := item.Status
		if itemStatus != "" {
			if !strings.Contains(item.Status, "/") {
				if itemStatus == utils.COMPANY_STATUS_FOREVER { //永续
					expireDay = "-"
				} else if itemStatus == utils.COMPANY_STATUS_TRY_OUT || itemStatus == utils.COMPANY_STATUS_FORMAL { //试用/正式
					if item.StartDate != "" && item.EndDate != "" {
						endDateTime, _ := time.Parse(utils.FormatDate, item.EndDate)
						endDateTime = endDateTime.AddDate(0, 0, 1)
						sub := endDateTime.Sub(time.Now())
						if sub < 0 {
							sub = 0
						}
						expireDay = fmt.Sprintf("%v", int(sub.Hours()/24))
					} else {
						expireDay = "-"
					}
				} else if itemStatus == utils.COMPANY_STATUS_LOSE {
					expireDay = "-"
				} else if itemStatus == utils.COMPANY_STATUS_FREEZE {
					if item.StartDate != "" && item.EndDate != "" {
						endDateTime, _ := time.Parse(utils.FormatDate, item.EndDate)
						endDateTime = endDateTime.AddDate(0, 0, 0)
						sub := endDateTime.Sub(time.Now())
						if sub < 0 {
							sub = 0
						}
						expireDay = fmt.Sprintf("%v", int(sub.Hours()/24))
					} else {
						expireDay = "-"
					}
				} else {
					expireDay = "-"
				}
			} else {
				statusArr := strings.Split(item.Status, "/")
				ficcStatus := statusArr[0]
				raiStatus := statusArr[1]
				var ficcEndDate, tryEndDate string
				var ficcExpireDay, tryExpireDay string
				if item.EndDate != "" {
					endDateArr := strings.Split(item.EndDate, "/")
					if len(endDateArr) == 1 {
						ficcEndDate = endDateArr[0]
					} else if len(endDateArr) > 1 {
						ficcEndDate = endDateArr[0]
						tryEndDate = endDateArr[1]
					}
					if ficcStatus == utils.COMPANY_STATUS_FOREVER { //永续
						ficcExpireDay = "-"
					} else if ficcStatus == utils.COMPANY_STATUS_TRY_OUT || ficcStatus == utils.COMPANY_STATUS_FORMAL { //试用/正式
						if ficcEndDate != "" {
							endDateTime, _ := time.Parse(utils.FormatDate, ficcEndDate)
							endDateTime = endDateTime.AddDate(0, 0, 1)
							sub := endDateTime.Sub(time.Now())
							if sub < 0 {
								sub = 0
							}
							ficcExpireDay = fmt.Sprintf("%v", int(sub.Hours()/24))
						} else {
							ficcExpireDay = "-"
						}
					} else if ficcStatus == utils.COMPANY_STATUS_LOSE { //流失
						ficcExpireDay = "-"
					} else if ficcStatus == utils.COMPANY_STATUS_FREEZE { //冻结
						if item.StartDate != "" && item.EndDate != "" {
							endDateTime, _ := time.Parse(utils.FormatDate, ficcEndDate)
							endDateTime = endDateTime.AddDate(0, 0, 0)
							sub := endDateTime.Sub(time.Now())
							if sub < 0 {
								sub = 0
							}
							ficcExpireDay = fmt.Sprintf("%v", int(sub.Hours()/24))
						} else {
							ficcExpireDay = "-"
						}
					} else {
						ficcExpireDay = "-"
					}

					if raiStatus == utils.COMPANY_STATUS_FOREVER { //永续
						tryExpireDay = "-"
					} else if raiStatus == utils.COMPANY_STATUS_TRY_OUT || raiStatus == utils.COMPANY_STATUS_FORMAL { //试用/正式
						if tryEndDate != "" {
							endDateTime, _ := time.Parse(utils.FormatDate, tryEndDate)
							endDateTime = endDateTime.AddDate(0, 0, 1)
							sub := endDateTime.Sub(time.Now())
							if sub < 0 {
								sub = 0
							}
							tryExpireDay = fmt.Sprintf("%v", int(sub.Hours()/24))
						} else {
							tryExpireDay = "-"
						}
					} else if raiStatus == utils.COMPANY_STATUS_LOSE { //流失
						tryExpireDay = "-"
					} else if raiStatus == utils.COMPANY_STATUS_FREEZE { //冻结
						if item.StartDate != "" && item.EndDate != "" {
							endDateTime, _ := time.Parse(utils.FormatDate, tryEndDate)
							endDateTime = endDateTime.AddDate(0, 0, 0)
							sub := endDateTime.Sub(time.Now())
							if sub < 0 {
								sub = 0
							}
							tryExpireDay = fmt.Sprintf("%v", int(sub.Hours()/24))
						} else {
							tryExpireDay = "-"
						}
					} else {
						tryExpireDay = "-"
					}
				}
				expireDay = ficcExpireDay + "/" + tryExpireDay
			}
		}
		list[i].ExpireDay = expireDay

		ficcKey := fmt.Sprint(item.CompanyId, "_", 1)
		//ficc
		if tmpCompanyProduct, ok := companyProductMap[ficcKey]; ok && (productId == 0 || productId == 1) {
			//套餐类型
			item.FiccPackageType = tmpCompanyProduct.PackageType

			//总阅读次数
			item.FiccView = tmpCompanyProduct.ViewTotal

			if !tmpCompanyProduct.LastViewTime.IsZero() {
				//最近一次阅读时间
				item.FiccLastViewTime = tmpCompanyProduct.LastViewTime.Format(utils.FormatDateTime)
			}

			item.FiccTryOutDay = tmpCompanyProduct.TryOutDayTotal
		}

		//权益
		raiKey := fmt.Sprint(item.CompanyId, "_", 2)
		if tmpCompanyProduct, ok := companyProductMap[raiKey]; ok && (productId == 0 || productId == 2) {
			//总阅读次数
			item.RaiView = tmpCompanyProduct.ViewTotal

			if !tmpCompanyProduct.LastViewTime.IsZero() {
				//最近一次阅读时间
				item.RaiLastViewTime = tmpCompanyProduct.LastViewTime.Format(utils.FormatDateTime)
			}
			item.RaiTryOutDay = tmpCompanyProduct.TryOutDayTotal
		}

	}

	companyLists := make([]*CompanyListItem, 0)
	//查询阅读次数
	if list == nil {
		companyLists = make([]*CompanyListItem, 0)
	} else {
		for _, v := range list {
			//viewTotal:=GetviewTotal(v.CompanyId)

			//活跃（客户状态）
			tmpStatus := v.Status
			//productIdSlice := strings.Split(v.ProductIds, "/")
			//statusSlice := strings.Split(v.Status, "/")

			// 试用客户子标签
			tryStageSlice := make([]company.TryStageSliceItem, 0)
			for _, vProductId := range []int{1, 2} {
				ficcKey := fmt.Sprint(v.CompanyId, "_", vProductId)
				//ficc
				if tmpCompanyProduct, ok := companyProductMap[ficcKey]; ok {
					if tmpCompanyProduct.Status == utils.COMPANY_STATUS_TRY_OUT {
						key := fmt.Sprint(v.CompanyId, "_", vProductId)
						if pro, ok := companyProductMap[key]; ok {
							tryItem := company.TryStageSliceItem{
								ProductId: vProductId,
								TryStage:  pro.TryStage,
							}
							if pro.SellerId == sysUser.AdminId { //产品销售ID和登录ID相等
								tryItem.HasPermission = true
							}
							tryStageSlice = append(tryStageSlice, tryItem)
						}
					}
				}
			}

			// 是否存在进行中的任务
			var todoStatus bool
			//是否支持确认完成待办任务
			var canConfirm bool
			var hiddenConfirm bool //是否隐藏确定完成按钮
			var hiddenCreate bool  //是否隐藏新增/编辑按钮
			hiddenConfirm = true
			hiddenCreate = true
			todoButtonColor := `green`
			//'无任务','未完成','已完成'
			if strings.Contains(v.TodoStatuss, "未完成") {
				todoButtonColor = "red"
				todoStatus = true
			} else if strings.Contains(v.TodoStatuss, "已完成") {
				todoButtonColor = "green"
			} else if strings.Contains(v.TodoStatuss, "无任务") {
				todoButtonColor = "gray"
			}
			for _, vProductId := range []int{1, 2} {
				ficcKey := fmt.Sprint(v.CompanyId, "_", vProductId)
				//ficc
				if tmpCompanyProduct, ok := companyProductMap[ficcKey]; ok {
					if tmpCompanyProduct.Status != utils.COMPANY_STATUS_LOSE && tmpCompanyProduct.Status != utils.COMPANY_STATUS_CLOSE { //非流失
						hiddenCreate = false
						switch sysUser.RoleTypeCode {
						case utils.ROLE_TYPE_CODE_FICC_ADMIN, utils.ROLE_TYPE_CODE_RAI_ADMIN, utils.ROLE_TYPE_CODE_FICC_GROUP, utils.ROLE_TYPE_CODE_RAI_GROUP:
							//部门管理员、ficc主管、权益组长
							hiddenConfirm = false //不展示
							if todoStatus {       //有任务，需要展示
								canConfirm = true
							}
						case utils.ROLE_TYPE_CODE_FICC_TEAM: //ficc组长
							if todoStatus { //有任务，需要展示
								canConfirm = true
							}
							if v.SellerId != sysUser.AdminId { //不是自己的客户
								hiddenConfirm = false //展示
							}
						case utils.ROLE_TYPE_CODE_RAI_SELLER: //权益销售
							if v.SellerId == sysUser.AdminId { //是自己的客户
								has := services.CheckRaiApprovePermission(sysUser.AdminId) //这些个权益销售是有权限的
								if has {
									if todoStatus { //有任务，需要展示
										canConfirm = true
									}
									hiddenConfirm = false //展示
								}
							}

						}
					}
				}
			}

			// To-Do任务状态为未完成的对应任务的截止日期-当前日期；
			tmpDeadline := v.Deadline
			if strings.Contains(v.TodoStatuss, "未完成") {
				if strings.Contains(v.TodoEndTimeStr, "/") {
					edtSlice := strings.Split(v.TodoEndTimeStr, "/")
					v.TodoEndTime, _ = time.ParseInLocation(utils.FormatDateTime, edtSlice[0], time.Local)
				} else {
					v.TodoEndTime, _ = time.ParseInLocation(utils.FormatDateTime, v.TodoEndTimeStr, time.Local)
				}
				tmpEndTime := v.TodoEndTime.Format(utils.FormatDate)
				if tmpEndTime == "0001-01-01" {
					tmpEndTime = ""
				}
				if tmpEndTime != "" {
					dlTime1 := time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.Local)
					dlTime2 := time.Date(v.TodoEndTime.Year(), v.TodoEndTime.Month(), v.TodoEndTime.Day(), 0, 0, 0, 0, time.Local)
					dldays := int(dlTime2.Sub(dlTime1).Hours() / 24)
					tmpDeadline = strconv.Itoa(dldays)
				}
			}

			var isShow bool //是否可见
			{
				switch sysUser.RoleTypeCode {
				case utils.ROLE_TYPE_CODE_ADMIN, utils.ROLE_TYPE_CODE_FICC_ADMIN, utils.ROLE_TYPE_CODE_RAI_ADMIN:
					//超管、部门管理员
					isShow = true
				case utils.ROLE_TYPE_CODE_FICC_GROUP, utils.ROLE_TYPE_CODE_RAI_GROUP, utils.ROLE_TYPE_CODE_FICC_TEAM: //ficc主管、权益主管、ficc组长
					ficcKey := fmt.Sprint(v.CompanyId, "_", sysUserProductId)
					if _, ok := companyProductMap[ficcKey]; ok {
						if _, ok2 := myChildSysGroupMap[v.GroupId]; ok2 {
							isShow = true
						}
					}
				case utils.ROLE_TYPE_CODE_RAI_SELLER, utils.ROLE_TYPE_CODE_FICC_SELLER: //权益销售、ficc销售
					ficcKey := fmt.Sprint(v.CompanyId, "_", sysUserProductId)
					if tmpCompanyProduct, ok := companyProductMap[ficcKey]; ok {
						if tmpCompanyProduct.SellerId == sysUser.AdminId { //是自己的客户
							isShow = true
						}
					}
				}
			}

			// 计算合同开始日期和结束日期之间的小时差
			duration := time.Since(v.FirstDate).Hours()
			hoursDiff := decimal.NewFromFloat(duration)

			// 计算总小时数
			const hoursPerYear = 24 * 365
			totalHours := decimal.NewFromInt(hoursPerYear)

			// 计算相差的年数，保留一位小数
			numYearDecimal := hoursDiff.Div(totalHours).Round(1)

			companyList := &CompanyListItem{
				CompanyId:        v.CompanyId,
				CompanyName:      v.CompanyName,
				CreditCode:       v.CreditCode,
				CompanyCode:      v.CompanyCode,
				StartDate:        v.StartDate,
				EndDate:          v.EndDate,
				LoseReason:       v.LoseReason,
				RenewalReason:    v.RenewalReason,
				FreezeReason:     v.FreezeReason,
				LossTime:         v.LossTime,
				Status:           tmpStatus,
				CompanyType:      v.CompanyType,
				ApproveStatus:    v.ApproveStatus,
				SellerName:       v.SellerName,
				SellerId:         v.SellerId,
				SellerIds:        v.SellerIds,
				ExpireDay:        v.ExpireDay,
				FreezeTime:       v.FreezeTime,
				GroupId:          v.GroupId,
				GroupIds:         v.GroupIds,
				DepartmentId:     v.DepartmentId,
				IndustryName:     v.IndustryName,
				IsSuspend:        v.IsSuspend,
				CreatedTime:      v.CreatedTime,
				Source:           v.Source,
				Province:         v.Province,
				City:             v.City,
				Address:          v.Address,
				Reasons:          v.Reasons,
				FreezeStartDate:  v.FreezeStartDate,
				FreezeEndDate:    v.FreezeEndDate,
				FreezeExpireDays: v.FreezeExpireDays,
				ProductId:        v.ProductId,
				FormalTime:       v.FormalTime,
				IsShared:         v.IsShared,
				RegionType:       v.RegionType,
				FiccPackageType:  v.FiccPackageType,
				FiccLastViewTime: v.FiccLastViewTime,
				RaiLastViewTime:  v.RaiLastViewTime,
				FiccView:         v.FiccView,
				RaiView:          v.RaiView,
				RoadShowTotal:    v.RoadShowTotal,
				FiccTryOutDay:    v.FiccTryOutDay,
				RaiTryOutDay:     v.RaiTryOutDay,

				TodoStatus:      todoStatus,
				CanConfirm:      canConfirm,
				HiddenConfirm:   hiddenConfirm,
				HiddenCreate:    hiddenCreate,
				TodoButtonColor: todoButtonColor,
				AllViewTotal:    v.AllViewTotal,
				Deadline:        tmpDeadline,
				IsShow:          isShow,
				TryStageSlice:   tryStageSlice,
				ShareSeller:     v.ShareSeller,
				ShareSellerId:   v.ShareSellerId,
				LatestServiceRecord: v.LatestServiceRecord.Format(utils.FormatDate2),
				ServiceYears: numYearDecimal.String(),
			}
			if strings.Contains(companyList.ApproveStatus, "已审批") {
				companyList.ApproveStatus = ""
			}

			companyLists = append(companyLists, companyList)
		}
	}
	if companyLists == nil {
		companyLists = make([]*CompanyListItem, 0)
	}
	page = paging.GetPaging(currentIndex, pageSize, total)
	resp.List = companyLists
	resp.Paging = page
	return
}
