package cast

import (
	"context"
	"errors"
	"fmt"
	"strings"
	"time"

	"fonchain-fiee/api/cast"
	"fonchain-fiee/pkg/cache"
	logicCast "fonchain-fiee/pkg/logic/cast"
	"fonchain-fiee/pkg/model/login"
	"fonchain-fiee/pkg/service"
	"fonchain-fiee/pkg/utils"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// PublishLogList 查询发布记录列表
func PublishLogList(ctx *gin.Context) {
	var req cast.ListPublishLogReq
	if err := ctx.ShouldBind(&req); err != nil {
		service.Error(ctx, err)
		return
	}
	resp, err := service.CastProvider.ListPublishLog(context.Background(), &req)
	if err != nil {
		service.Error(ctx, err)
		return
	}
	service.Success(ctx, resp)
}

// PublishLogListExport 导出发布记录列表 Excel
func PublishLogListExport(ctx *gin.Context) {
	var req cast.ListPublishLogReq
	if err := ctx.ShouldBind(&req); err != nil {
		service.Error(ctx, errors.New("绑定参数失败"))
		return
	}

	loginInfo := login.GetUserInfoFromC(ctx)
	newCtx := NewCtxWithUserInfo(ctx)

	lockKey := "PublishLogListExport" + fmt.Sprint(loginInfo.ID)
	replay := cache.RedisClient.SetNX(lockKey, time.Now().Unix(), time.Minute*30)
	if !replay.Val() {
		service.Error(ctx, errors.New("已有导出任务在进行中，请稍后再试"))
		return
	}
	defer cache.RedisClient.Del(lockKey)

	const batchSize = 5000
	var allData []*cast.PublishLogInfo

	page := int32(1)
	if req.Page > 0 {
		page = req.Page
	}

	originalPageSize := req.PageSize
	req.PageSize = batchSize

	zap.L().Info("开始分批导出发布记录列表", zap.Int32("batchSize", batchSize))

	for {
		req.Page = page
		zap.L().Info("获取第 N 页数据", zap.Int32("page", page), zap.Int32("pageSize", req.PageSize))

		resp, err := service.CastProvider.ListPublishLog(newCtx, &req)
		if err != nil {
			zap.L().Error("获取发布记录失败", zap.Error(err), zap.Int32("page", page))
			service.Error(ctx, errors.New("获取发布记录失败"))
			return
		}

		if resp == nil || len(resp.Data) == 0 {
			zap.L().Info("没有更多数据", zap.Int32("page", page))
			break
		}

		allData = append(allData, resp.Data...)
		zap.L().Info("获取数据成功",
			zap.Int32("page", page),
			zap.Int("本批次数量", len(resp.Data)),
			zap.Int("累计总数", len(allData)))

		if len(resp.Data) < batchSize {
			zap.L().Info("已到最后一页", zap.Int32("page", page))
			break
		}
		page++
	}

	req.PageSize = originalPageSize
	zap.L().Info("数据获取完成，开始生成Excel", zap.Int("总数据量", len(allData)))

	if len(allData) == 0 {
		service.Error(ctx, errors.New("没有数据可导出"))
		return
	}

	fileName := fmt.Sprintf("发布记录_%s.xlsx", time.Now().Format("20060102150405"))
	filePath := fmt.Sprintf("./runtime/%d/%s", loginInfo.ID, fileName)
	utils.CheckDirPath("./runtime/"+fmt.Sprint(loginInfo.ID), true)

	var logicWork = new(logicCast.Work)
	if err := logicWork.ExportPublishLogList(allData, filePath); err != nil {
		zap.L().Error("生成Excel失败", zap.Error(err))
		service.Error(ctx, err)
		return
	}

	scheme := "http"
	if ctx.GetHeader("X-Forwarded-Proto") == "https" {
		scheme = "https"
	}
	exportUrl := fmt.Sprintf("%s://%s/api/fiee/static/%s", scheme, ctx.Request.Host, strings.Replace(filePath, "./runtime/", "", 1))

	zap.L().Info("Excel导出成功", zap.String("文件名", fileName), zap.Int("记录数", len(allData)))
	service.Success(ctx, map[string]interface{}{
		"url": exportUrl,
	})
}
