package postgres

import (
	"context"

	"gorm.io/gorm"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
)

// PollingManualTriggerLogStore 手动触发日志存储
type PollingManualTriggerLogStore struct {
	db *gorm.DB
}

// NewPollingManualTriggerLogStore 创建手动触发日志存储实例
func NewPollingManualTriggerLogStore(db *gorm.DB) *PollingManualTriggerLogStore {
	return &PollingManualTriggerLogStore{db: db}
}

// Create 创建手动触发日志
func (s *PollingManualTriggerLogStore) Create(ctx context.Context, log *model.PollingManualTriggerLog) error {
	return s.db.WithContext(ctx).Create(log).Error
}

// GetByID 根据ID获取手动触发日志
func (s *PollingManualTriggerLogStore) GetByID(ctx context.Context, id uint) (*model.PollingManualTriggerLog, error) {
	var log model.PollingManualTriggerLog
	if err := s.db.WithContext(ctx).First(&log, id).Error; err != nil {
		return nil, err
	}
	return &log, nil
}

// Update 更新手动触发日志
func (s *PollingManualTriggerLogStore) Update(ctx context.Context, log *model.PollingManualTriggerLog) error {
	return s.db.WithContext(ctx).Save(log).Error
}

// List 分页获取手动触发日志
func (s *PollingManualTriggerLogStore) List(ctx context.Context, page, pageSize int, taskType string, triggeredBy *uint) ([]*model.PollingManualTriggerLog, int64, error) {
	var logs []*model.PollingManualTriggerLog
	var total int64

	query := s.db.WithContext(ctx).Model(&model.PollingManualTriggerLog{})
	if taskType != "" {
		query = query.Where("task_type = ?", taskType)
	}
	if triggeredBy != nil {
		query = query.Where("triggered_by = ?", *triggeredBy)
	}

	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	if err := query.Order("triggered_at DESC").Offset(offset).Limit(pageSize).Find(&logs).Error; err != nil {
		return nil, 0, err
	}

	return logs, total, nil
}

// GetRunning 获取正在运行的触发任务
func (s *PollingManualTriggerLogStore) GetRunning(ctx context.Context, triggeredBy uint) ([]*model.PollingManualTriggerLog, error) {
	var logs []*model.PollingManualTriggerLog
	if err := s.db.WithContext(ctx).
		Where("triggered_by = ? AND status IN (?, ?)", triggeredBy, constants.PollingManualTriggerStatusPending, constants.PollingManualTriggerStatusProcessing).
		Order("triggered_at DESC").
		Find(&logs).Error; err != nil {
		return nil, err
	}
	return logs, nil
}

// UpdateProgress 更新触发进度
func (s *PollingManualTriggerLogStore) UpdateProgress(ctx context.Context, id uint, processedCount, successCount, failedCount int) error {
	return s.db.WithContext(ctx).Model(&model.PollingManualTriggerLog{}).
		Where("id = ?", id).
		Updates(map[string]any{
			"processed_count": processedCount,
			"success_count":   successCount,
			"failed_count":    failedCount,
		}).Error
}

// UpdateStatus 更新触发状态
func (s *PollingManualTriggerLogStore) UpdateStatus(ctx context.Context, id uint, status string) error {
	updates := map[string]any{"status": status}
	if status == constants.PollingManualTriggerStatusCompleted || status == constants.PollingManualTriggerStatusCancelled {
		updates["completed_at"] = gorm.Expr("CURRENT_TIMESTAMP")
	}
	return s.db.WithContext(ctx).Model(&model.PollingManualTriggerLog{}).
		Where("id = ?", id).
		Updates(updates).Error
}

// CountTodayTriggers 统计今日触发次数
func (s *PollingManualTriggerLogStore) CountTodayTriggers(ctx context.Context, triggeredBy uint) (int64, error) {
	var count int64
	if err := s.db.WithContext(ctx).Model(&model.PollingManualTriggerLog{}).
		Where("triggered_by = ? AND DATE(triggered_at) = CURRENT_DATE", triggeredBy).
		Count(&count).Error; err != nil {
		return 0, err
	}
	return count, nil
}
