package repositories

import (
	"log"
	"time"

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

// TrendData 趋势数据
type TrendData struct {
	Date  string  `json:"date"`
	Count int     `json:"value"`
	YoY   float64 `json:"yoy"`
	MoM   float64 `json:"mom"`
}

// GetPosts 获取所有博客文章（支持搜索、分类、标签筛选）
func GetPosts(keyword string, categoryID uint, tagID uint, columnID uint) ([]models.Post, error) {
	var posts []models.Post
	query := config.DB.Model(&models.Post{}).
		Preload("Category").
		Preload("Column").
		Preload("Tags").
		Where("is_published = ? AND deleted_at = ?", 1, 0)

	if tagID > 0 {
		query = query.Joins("JOIN post_tags pt ON posts.id = pt.post_id").
			Where("pt.tag_id = ?", tagID)
	}

	if categoryID > 0 {
		query = query.Where("category_id = ?", categoryID)
	}

	if columnID > 0 {
		query = query.Where("column_id = ?", columnID)
	}

	if keyword != "" {
		likeKeyword := "%" + keyword + "%"
		query = query.Where("(MATCH(title, content) AGAINST(? IN BOOLEAN MODE) OR title LIKE ? OR content LIKE ?)",
			keyword, likeKeyword, likeKeyword)
	}

	err := query.Order("created_at DESC").Find(&posts).Error
	if err != nil {
		log.Printf("Error querying posts: %v", err)
		return nil, err
	}

	return posts, nil
}

// GetPostByID 根据ID获取博客文章
func GetPostByID(id uint) (*models.Post, error) {
	var post models.Post
	// 显式选择所有字段，确保 content 字段被加载
	err := config.DB.Model(&models.Post{}).
		Select("id", "title", "category_id", "column_id", "excerpt", "content", "read_count", "is_published", "created_at", "updated_at", "deleted_at").
		Preload("Category").
		Preload("Column").
		Preload("Tags").
		Where("id = ? AND is_published = ? AND deleted_at = ?", id, 1, 0).
		First(&post).Error

	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		log.Printf("Error getting post by ID: %v", err)
		return nil, err
	}

	// 更新阅读量
	config.DB.Model(&models.Post{}).
		Where("id = ?", id).
		UpdateColumn("read_count", gorm.Expr("read_count + ?", 1))

	return &post, nil
}

// GetAllPosts 获取所有博客文章（包括未发布的，后台用）
func GetAllPosts(page, pageSize int) ([]models.Post, int64, error) {
	offset := (page - 1) * pageSize

	var posts []models.Post
	var total int64

	// Count total
	err := config.DB.Model(&models.Post{}).
		Where("deleted_at = ?", 0).
		Count(&total).Error
	if err != nil {
		log.Printf("Error counting posts: %v", err)
		return nil, 0, err
	}

	// Get posts
	err = config.DB.Model(&models.Post{}).
		Preload("Category").
		Preload("Column").
		Preload("Tags").
		Where("deleted_at = ?", 0).
		Order("created_at DESC").
		Limit(pageSize).
		Offset(offset).
		Find(&posts).Error

	if err != nil {
		log.Printf("Error querying all posts: %v", err)
		return nil, 0, err
	}

	return posts, total, nil
}

// CreatePost 创建博客文章
func CreatePost(post *models.Post) error {
	err := config.DB.Create(post).Error
	if err != nil {
		log.Printf("Error creating post: %v", err)
		return err
	}

	// Insert Tags
	if len(post.Tags) > 0 {
		err = config.DB.Model(post).Association("Tags").Replace(post.Tags)
		if err != nil {
			log.Printf("Error associating tags: %v", err)
			return err
		}
	}

	// Handle column association if ColumnID is set
	if post.ColumnID != nil && *post.ColumnID > 0 {
		// Add to column_posts table
		err = AddPostToColumn(*post.ColumnID, post.ID, 0)
		if err != nil {
			log.Printf("Error adding post to column: %v", err)
			// Don't fail the whole operation, just log
		}
	}

	return nil
}

// UpdatePost 更新博客文章
func UpdatePost(post *models.Post) error {
	updateData := map[string]interface{}{
		"title":        post.Title,
		"category_id":  post.CategoryID,
		"excerpt":      post.Excerpt,
		"content":      post.Content,
		"is_published": post.IsPublished,
		"updated_at":   time.Now().Unix(),
	}

	// Update column_id if provided
	if post.ColumnID != nil {
		updateData["column_id"] = post.ColumnID
	} else {
		// Set to NULL if explicitly set to nil
		updateData["column_id"] = nil
	}

	err := config.DB.Model(&models.Post{}).
		Where("id = ? AND deleted_at = ?", post.ID, 0).
		Updates(updateData).Error

	if err != nil {
		log.Printf("Error updating post: %v", err)
		return err
	}

	// Update Tags
	if len(post.Tags) > 0 {
		err = config.DB.Model(&models.Post{ID: post.ID}).Association("Tags").Replace(post.Tags)
		if err != nil {
			log.Printf("Error updating tags: %v", err)
			return err
		}
	} else {
		// Clear all tags
		err = config.DB.Model(&models.Post{ID: post.ID}).Association("Tags").Clear()
		if err != nil {
			log.Printf("Error clearing tags: %v", err)
			return err
		}
	}

	// Handle column association
	// Always sync column_posts table with column_id
	// First, remove from all columns
	err = config.DB.Where("post_id = ?", post.ID).Delete(&models.ColumnPost{}).Error
	if err != nil {
		log.Printf("Error removing post from columns: %v", err)
		// Don't fail the whole operation
	}

	// Then add to new column if specified
	if post.ColumnID != nil && *post.ColumnID > 0 {
		err = AddPostToColumn(*post.ColumnID, post.ID, 0)
		if err != nil {
			log.Printf("Error adding post to column: %v", err)
			// Don't fail the whole operation
		}
	}

	return nil
}

// UpdatePostStatus 更新文章状态
func UpdatePostStatus(id uint, status int) error {
	err := config.DB.Model(&models.Post{}).
		Where("id = ? AND deleted_at = ?", id, 0).
		Updates(map[string]interface{}{
			"is_published": status,
			"updated_at":   time.Now().Unix(),
		}).Error
	return err
}

// DeletePost 删除博客文章 (Soft Delete)
func DeletePost(id uint) error {
	err := config.DB.Model(&models.Post{}).
		Where("id = ?", id).
		Update("deleted_at", time.Now().Unix()).Error
	if err != nil {
		log.Printf("Error deleting post: %v", err)
		return err
	}
	return nil
}

// GetPostCount 获取文章总数
func GetPostCount() (int, error) {
	var count int64
	err := config.DB.Model(&models.Post{}).
		Where("deleted_at = ?", 0).
		Count(&count).Error
	if err != nil {
		log.Printf("Error getting post count: %v", err)
		return 0, err
	}
	return int(count), nil
}

// BuildPostResponse 构建博客文章响应
func BuildPostResponse(post *models.Post, includeContent bool) *models.PostResponse {
	// Format CreatedAt to Date string
	dateStr := time.Unix(post.CreatedAt, 0).Format("2006-01-02")

	catName := ""
	catSlug := ""
	if post.Category != nil {
		catName = post.Category.Name
		catSlug = post.Category.Slug
	}

	colName := ""
	colSlug := ""
	if post.Column != nil {
		colName = post.Column.Name
		// 如果 Column 有 Slug 字段，可以在这里添加
		// colSlug = post.Column.Slug
	}

	response := &models.PostResponse{
		ID:           post.ID,
		Title:        post.Title,
		CategoryID:   post.CategoryID,
		CategoryName: catName,
		CategorySlug: catSlug,
		ColumnID:     post.ColumnID,
		ColumnName:   colName,
		ColumnSlug:   colSlug,
		Date:         dateStr,
		Excerpt:      post.Excerpt,
		Tags:         post.Tags,
		IsPublished:  post.IsPublished,
		ReadCount:    post.ReadCount,
	}

	if includeContent {
		// 使用指针类型，确保即使内容为空字符串也会出现在 JSON 中
		content := post.Content
		response.Content = &content
	}

	return response
}

// BuildPostsResponse 构建博客文章列表响应
func BuildPostsResponse(posts []models.Post) []models.PostResponse {
	var responses []models.PostResponse
	for _, post := range posts {
		responses = append(responses, *BuildPostResponse(&post, false))
	}
	return responses
}

// SavePostHistory 保存文章历史记录
func SavePostHistory(post *models.Post, modifiedBy uint) error {
	// 获取当前最大版本号
	var maxVersion int
	err := config.DB.Model(&models.PostHistory{}).
		Where("post_id = ?", post.ID).
		Select("COALESCE(MAX(version), 0)").
		Scan(&maxVersion).Error
	if err != nil {
		log.Printf("Error getting max version: %v", err)
		return err
	}

	history := &models.PostHistory{
		PostID:      post.ID,
		Version:     maxVersion + 1,
		Title:       post.Title,
		CategoryID:  post.CategoryID,
		Excerpt:     post.Excerpt,
		Content:     post.Content,
		IsPublished: post.IsPublished,
		ModifiedBy:  modifiedBy,
	}

	err = config.DB.Create(history).Error
	if err != nil {
		log.Printf("Error saving post history: %v", err)
		return err
	}

	return nil
}

// GetTopPosts 获取热门文章 (按阅读量)
func GetTopPosts(limit int) ([]models.Post, error) {
	var posts []models.Post
	err := config.DB.Model(&models.Post{}).
		Select("id, title, read_count").
		Where("is_published = ? AND deleted_at = ?", 1, 0).
		Order("read_count DESC").
		Limit(limit).
		Find(&posts).Error
	if err != nil {
		return nil, err
	}
	return posts, nil
}

// GetNewPostsTrend 获取新增文章趋势
func GetNewPostsTrend(startDate, endDate string) ([]TrendData, 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.Post{}).
		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 []TrendData
	err := query.Group("date").
		Order("date ASC").
		Scan(&results).Error

	if err != nil {
		return nil, err
	}

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

	// 生成完整日期列表
	var fullResults []TrendData
	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 {
			data.YoY = 0
			data.MoM = 0
			fullResults = append(fullResults, data)
		} else {
			// 填充0值
			fullResults = append(fullResults, TrendData{
				Date:  dateStr,
				Count: 0,
				YoY:   0,
				MoM:   0,
			})
		}
		current = current.AddDate(0, 0, 1)
	}

	return fullResults, nil
}

// GetPostHistory 获取文章修改历史
func GetPostHistory(postID uint) ([]models.PostHistory, error) {
	var history []models.PostHistory
	err := config.DB.Model(&models.PostHistory{}).
		Where("post_id = ?", postID).
		Order("version DESC").
		Find(&history).Error
	if err != nil {
		return nil, err
	}
	return history, nil
}

// GetPostHistoryByVersion 获取特定版本的历史记录
func GetPostHistoryByVersion(postID uint, version uint) (*models.PostHistory, error) {
	var h models.PostHistory
	err := config.DB.Model(&models.PostHistory{}).
		Where("post_id = ? AND version = ?", postID, version).
		First(&h).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, err
	}
	return &h, nil
}

// BuildPostHistoryResponse 构建历史记录响应
func BuildPostHistoryResponse(h *models.PostHistory) *models.PostHistoryResponse {
	return &models.PostHistoryResponse{
		ID:          h.ID,
		PostID:      h.PostID,
		Version:     h.Version,
		Title:       h.Title,
		CategoryID:  h.CategoryID,
		Date:        time.Unix(h.CreatedAt, 0).Format("2006-01-02"),
		IsPublished: h.IsPublished,
		ModifiedBy:  h.ModifiedBy,
		ModifiedAt:  time.Unix(h.ModifiedAt, 0).Format("2006-01-02 15:04:05"),
		CreatedAt:   time.Unix(h.CreatedAt, 0).Format("2006-01-02 15:04:05"),
	}
}

// BuildPostHistoryResponses 构建历史记录列表响应
func BuildPostHistoryResponses(history []models.PostHistory) []models.PostHistoryResponse {
	var responses []models.PostHistoryResponse
	for _, h := range history {
		responses = append(responses, *BuildPostHistoryResponse(&h))
	}
	return responses
}
