package repositories

import (
	"log"
	"time"

	"github.com/niangaodev/art-code/config"
	"github.com/niangaodev/art-code/models"
	"github.com/niangaodev/art-code/utils"
)

// CreateOperationLog 创建操作日志
func CreateOperationLog(operationLog *models.OperationLog) error {
	err := config.DB.Create(operationLog).Error
	if err != nil {
		log.Printf("Error creating operation log: %v", err)
		return err
	}
	return nil
}

// GetOperationLogs 获取操作日志列表
func GetOperationLogs(page, pageSize int, filter OperationLogFilter) ([]models.OperationLog, int64, error) {
	offset := (page - 1) * pageSize

	query := config.DB.Model(&models.OperationLog{}).
		Where("deleted_at = ?", 0)

	if filter.Action != "" {
		query = query.Where("action LIKE ?", "%"+filter.Action+"%")
	}
	if filter.Method != "" {
		query = query.Where("method = ?", filter.Method)
	}
	if filter.Status > 0 {
		query = query.Where("status = ?", filter.Status)
	}
	if filter.UserID > 0 {
		query = query.Where("user_id = ?", filter.UserID)
	}
	if filter.StartDate != "" {
		startUnix := parseDateToUnix(filter.StartDate, false)
		if startUnix > 0 {
			query = query.Where("created_at >= ?", startUnix)
		}
	}
	if filter.EndDate != "" {
		endUnix := parseDateToUnix(filter.EndDate, true)
		if endUnix > 0 {
			query = query.Where("created_at <= ?", endUnix)
		}
	}

	var total int64
	if err := query.Count(&total).Error; err != nil {
		log.Printf("Error counting operation logs: %v", err)
		return nil, 0, err
	}

	var logs []models.OperationLog
	err := query.Order("created_at DESC").
		Limit(pageSize).
		Offset(offset).
		Find(&logs).Error
	if err != nil {
		log.Printf("Error querying operation logs: %v", err)
		return nil, 0, err
	}

	return logs, total, nil
}

// BuildOperationLogResponse 构建操作日志响应
func BuildOperationLogResponse(log *models.OperationLog) *models.OperationLogResponse {
	action := log.Action
	if action == "" {
		action = utils.GetOperationAction(log.Path, log.Method)
	}

	return &models.OperationLogResponse{
		ID:        log.ID,
		UserID:    log.UserID,
		Username:  log.Username,
		IP:        log.IP,
		Region:    log.Region,
		Path:      log.Path,
		Method:    log.Method,
		Action:    action,
		Params:    log.Params,
		Status:    log.Status,
		Duration:  log.Duration,
		CreatedAt: time.Unix(log.CreatedAt, 0).Format("2006-01-02 15:04:05"),
	}
}

// BuildOperationLogsResponse 构建操作日志列表响应
func BuildOperationLogsResponse(logs []models.OperationLog) []models.OperationLogResponse {
	var responses []models.OperationLogResponse
	for _, log := range logs {
		responses = append(responses, *BuildOperationLogResponse(&log))
	}
	return responses
}

// OperationTrendData 操作趋势数据
type OperationTrendData struct {
	Date  string `json:"date"`
	Count int    `json:"value"`
}

// GetOperationTrend 获取操作趋势（按日期统计）
func GetOperationTrend(startDate, endDate string) ([]OperationTrendData, error) {
	// 确定日期范围
	var startTime, endTime time.Time
	if startDate != "" {
		startUnix := parseDateToUnix(startDate, false)
		startTime = time.Unix(startUnix, 0)
	} else {
		startTime = time.Now().AddDate(0, 0, -6)
		startTime = time.Date(startTime.Year(), startTime.Month(), startTime.Day(), 0, 0, 0, 0, time.Local)
	}

	if endDate != "" {
		endUnix := parseDateToUnix(endDate, true)
		endTime = time.Unix(endUnix, 0)
	} else {
		endTime = time.Now()
		endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 23, 59, 59, 0, time.Local)
	}

	// 查询数据库
	query := config.DB.Model(&models.OperationLog{}).
		Select("FROM_UNIXTIME(created_at, '%Y-%m-%d') as date, COUNT(*) as count").
		Where("deleted_at = ?", 0).
		Where("created_at >= ?", startTime.Unix()).
		Where("created_at <= ?", endTime.Unix())

	var results []OperationTrendData
	err := query.Group("date").
		Order("date ASC").
		Scan(&results).Error

	if err != nil {
		return nil, err
	}

	// 创建日期到数据的映射
	resultMap := make(map[string]OperationTrendData)
	for _, r := range results {
		resultMap[r.Date] = r
	}

	// 生成完整日期列表
	var fullResults []OperationTrendData
	current := time.Date(startTime.Year(), startTime.Month(), startTime.Day(), 0, 0, 0, 0, time.Local)
	endDay := time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, time.Local)

	for !current.After(endDay) {
		dateStr := current.Format("2006-01-02")
		if data, exists := resultMap[dateStr]; exists {
			fullResults = append(fullResults, data)
		} else {
			// 填充0值
			fullResults = append(fullResults, OperationTrendData{
				Date:  dateStr,
				Count: 0,
			})
		}
		current = current.AddDate(0, 0, 1)
	}

	return fullResults, nil
}
