package service

import (
	"context"
	"database/sql"
	"time"

	"bdrp-server/app/main/model"
	"bdrp-server/common/xerr"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

type AdminPromotionLinkStatsService struct {
	logx.Logger
	AdminPromotionLinkModel             model.AdminPromotionLinkModel
	AdminPromotionLinkStatsTotalModel   model.AdminPromotionLinkStatsTotalModel
	AdminPromotionLinkStatsHistoryModel model.AdminPromotionLinkStatsHistoryModel
}

func NewAdminPromotionLinkStatsService(
	AdminPromotionLinkModel model.AdminPromotionLinkModel,
	AdminPromotionLinkStatsTotalModel model.AdminPromotionLinkStatsTotalModel,
	AdminPromotionLinkStatsHistoryModel model.AdminPromotionLinkStatsHistoryModel,
) *AdminPromotionLinkStatsService {
	return &AdminPromotionLinkStatsService{
		Logger:                              logx.WithContext(context.Background()),
		AdminPromotionLinkModel:             AdminPromotionLinkModel,
		AdminPromotionLinkStatsTotalModel:   AdminPromotionLinkStatsTotalModel,
		AdminPromotionLinkStatsHistoryModel: AdminPromotionLinkStatsHistoryModel,
	}
}

// ensureTotalStats 确保总统计记录存在，如果不存在则创建
func (s *AdminPromotionLinkStatsService) ensureTotalStats(ctx context.Context, session sqlx.Session, linkId int64) (*model.AdminPromotionLinkStatsTotal, error) {
	totalStats, err := s.AdminPromotionLinkStatsTotalModel.FindOneByLinkId(ctx, linkId)
	if err != nil {
		if errors.Is(err, model.ErrNotFound) {
			// 如果记录不存在，创建新记录
			totalStats = &model.AdminPromotionLinkStatsTotal{
				LinkId:     linkId,
				ClickCount: 0,
				PayCount:   0,
				PayAmount:  0,
			}
			_, err = s.AdminPromotionLinkStatsTotalModel.Insert(ctx, session, totalStats)
			if err != nil {
				return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建总统计记录失败: %+v", err)
			}
			// 重新获取创建后的记录
			totalStats, err = s.AdminPromotionLinkStatsTotalModel.FindOneByLinkId(ctx, linkId)
			if err != nil {
				return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取新创建的总统计记录失败: %+v", err)
			}
		} else {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询总统计失败: %+v", err)
		}
	}
	return totalStats, nil
}

// ensureHistoryStats 确保历史统计记录存在，如果不存在则创建
func (s *AdminPromotionLinkStatsService) ensureHistoryStats(ctx context.Context, session sqlx.Session, linkId int64, today time.Time) (*model.AdminPromotionLinkStatsHistory, error) {
	historyStats, err := s.AdminPromotionLinkStatsHistoryModel.FindOneByLinkIdStatsDate(ctx, linkId, today)
	if err != nil {
		if errors.Is(err, model.ErrNotFound) {
			// 如果记录不存在，创建新记录
			historyStats = &model.AdminPromotionLinkStatsHistory{
				LinkId:     linkId,
				StatsDate:  today,
				ClickCount: 0,
				PayCount:   0,
				PayAmount:  0,
			}
			_, err = s.AdminPromotionLinkStatsHistoryModel.Insert(ctx, session, historyStats)
			if err != nil {
				return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建今日统计记录失败: %+v", err)
			}
			// 重新获取创建后的记录
			historyStats, err = s.AdminPromotionLinkStatsHistoryModel.FindOneByLinkIdStatsDate(ctx, linkId, today)
			if err != nil {
				return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取新创建的今日统计记录失败: %+v", err)
			}
		} else {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询今日统计记录失败: %+v", err)
		}
	}
	return historyStats, nil
}

// UpdateLinkStats 更新推广链接统计
func (s *AdminPromotionLinkStatsService) UpdateLinkStats(ctx context.Context, linkId int64) error {
	return s.AdminPromotionLinkStatsTotalModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error {
		// 确保总统计记录存在
		totalStats, err := s.ensureTotalStats(ctx, session, linkId)
		if err != nil {
			return err
		}

		// 更新总统计
		totalStats.ClickCount++
		totalStats.LastClickTime = sql.NullTime{Time: time.Now(), Valid: true}
		err = s.AdminPromotionLinkStatsTotalModel.UpdateWithVersion(ctx, session, totalStats)
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新总统计失败: %+v", err)
		}

		// 确保历史统计记录存在
		now := time.Now()
		today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
		historyStats, err := s.ensureHistoryStats(ctx, session, linkId, today)
		if err != nil {
			return err
		}

		// 更新历史统计
		historyStats.ClickCount++
		historyStats.LastClickTime = sql.NullTime{Time: time.Now(), Valid: true}
		err = s.AdminPromotionLinkStatsHistoryModel.UpdateWithVersion(ctx, session, historyStats)
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新历史统计失败: %+v", err)
		}

		return nil
	})
}

// UpdatePaymentStats 更新付费统计
func (s *AdminPromotionLinkStatsService) UpdatePaymentStats(ctx context.Context, linkId int64, amount float64) error {
	return s.AdminPromotionLinkStatsTotalModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error {
		// 确保总统计记录存在
		totalStats, err := s.ensureTotalStats(ctx, session, linkId)
		if err != nil {
			return err
		}

		// 更新总统计
		totalStats.PayCount++
		totalStats.PayAmount += amount
		totalStats.LastPayTime = sql.NullTime{Time: time.Now(), Valid: true}
		err = s.AdminPromotionLinkStatsTotalModel.UpdateWithVersion(ctx, session, totalStats)
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新总统计失败: %+v", err)
		}

		// 确保历史统计记录存在
		now := time.Now()
		today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
		historyStats, err := s.ensureHistoryStats(ctx, session, linkId, today)
		if err != nil {
			return err
		}

		// 更新历史统计
		historyStats.PayCount++
		historyStats.PayAmount += amount
		historyStats.LastPayTime = sql.NullTime{Time: time.Now(), Valid: true}
		err = s.AdminPromotionLinkStatsHistoryModel.UpdateWithVersion(ctx, session, historyStats)
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新历史统计失败: %+v", err)
		}

		return nil
	})
}

// CreateLinkStats 创建新的推广链接统计记录
func (s *AdminPromotionLinkStatsService) CreateLinkStats(ctx context.Context, linkId int64) error {
	return s.AdminPromotionLinkStatsTotalModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error {
		// 检查总统计记录是否已存在
		_, err := s.AdminPromotionLinkStatsTotalModel.FindOneByLinkId(ctx, linkId)
		if err == nil {
			// 记录已存在，不需要创建
			return nil
		}
		if err != model.ErrNotFound {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询总统计记录失败: %+v", err)
		}

		// 创建总统计记录
		totalStats := &model.AdminPromotionLinkStatsTotal{
			LinkId:     linkId,
			ClickCount: 0,
			PayCount:   0,
			PayAmount:  0,
		}
		_, err = s.AdminPromotionLinkStatsTotalModel.Insert(ctx, session, totalStats)
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建总统计记录失败: %+v", err)
		}

		// 创建今日历史统计记录
		now := time.Now()
		today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
		historyStats := &model.AdminPromotionLinkStatsHistory{
			LinkId:     linkId,
			StatsDate:  today,
			ClickCount: 0,
			PayCount:   0,
			PayAmount:  0,
		}
		_, err = s.AdminPromotionLinkStatsHistoryModel.Insert(ctx, session, historyStats)
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建历史统计记录失败: %+v", err)
		}

		return nil
	})
}
