package repositories

import (
	"log"
	"time"

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

// ReplaceSnippetPosts 全量替换代码片段关联的文章
func ReplaceSnippetPosts(snippetID uint, postIDs []uint) error {
	return config.DB.Transaction(func(tx *gorm.DB) error {
		if err := tx.Where("snippet_id = ?", snippetID).Delete(&models.PostSnippet{}).Error; err != nil {
			log.Printf("Error clearing snippet posts: %v", err)
			return err
		}
		if len(postIDs) == 0 {
			return nil
		}
		now := time.Now().Unix()
		for i, postID := range postIDs {
			row := models.PostSnippet{
				PostID:    postID,
				SnippetID: snippetID,
				SortOrder: uint(i),
				CreatedAt: now,
			}
			if err := tx.Create(&row).Error; err != nil {
				log.Printf("Error creating post_snippet: %v", err)
				return err
			}
		}
		return nil
	})
}

// GetPostsBySnippetID 获取代码片段关联的文章
func GetPostsBySnippetID(snippetID uint) ([]models.PostBrief, error) {
	var posts []models.Post
	err := config.DB.Table("posts").
		Select("posts.id, posts.title").
		Joins("INNER JOIN post_snippets ps ON ps.post_id = posts.id").
		Where("ps.snippet_id = ? AND posts.deleted_at = ?", snippetID, 0).
		Order("ps.sort_order ASC, ps.created_at ASC").
		Find(&posts).Error
	if err != nil {
		log.Printf("Error getting posts by snippet ID: %v", err)
		return nil, err
	}
	result := make([]models.PostBrief, 0, len(posts))
	for _, p := range posts {
		result = append(result, models.PostBrief{ID: p.ID, Title: p.Title})
	}
	return result, nil
}

// GetSnippetsByPostID 获取文章关联的代码片段（不含完整 code）
func GetSnippetsByPostID(postID uint) ([]models.SnippetBrief, error) {
	var snippets []models.Snippet
	err := config.DB.Table("snippets").
		Select("snippets.id, snippets.title, snippets.type, snippets.code_type_id").
		Joins("INNER JOIN post_snippets ps ON ps.snippet_id = snippets.id").
		Where("ps.post_id = ? AND snippets.deleted_at = ?", postID, 0).
		Order("ps.sort_order ASC, ps.created_at ASC").
		Find(&snippets).Error
	if err != nil {
		log.Printf("Error getting snippets by post ID: %v", err)
		return nil, err
	}
	result := make([]models.SnippetBrief, 0, len(snippets))
	typeIDs := make([]uint, 0, len(snippets))
	for _, s := range snippets {
		if s.CodeTypeID > 0 {
			typeIDs = append(typeIDs, s.CodeTypeID)
		}
	}
	codeTypeMap := GetCodeTypesByIDs(typeIDs)
	for _, s := range snippets {
		brief := models.SnippetBrief{
			ID:    s.ID,
			Title: s.Title,
			Type:  s.Type,
		}
		if ct := codeTypeMap[s.CodeTypeID]; ct != nil {
			r := BuildCodeTypeResponse(ct)
			brief.CodeType = &r
			if brief.Type == "" {
				brief.Type = ct.Name
			}
		}
		result = append(result, brief)
	}
	return result, nil
}

// GetPostsBySnippetIDs 批量获取多个片段关联的文章
func GetPostsBySnippetIDs(snippetIDs []uint) map[uint][]models.PostBrief {
	result := make(map[uint][]models.PostBrief)
	if len(snippetIDs) == 0 {
		return result
	}
	type row struct {
		SnippetID uint
		PostID    uint
		Title     string
		SortOrder uint
	}
	var rows []row
	err := config.DB.Table("post_snippets ps").
		Select("ps.snippet_id, ps.post_id, p.title, ps.sort_order").
		Joins("INNER JOIN posts p ON p.id = ps.post_id").
		Where("ps.snippet_id IN ? AND p.deleted_at = ?", snippetIDs, 0).
		Order("ps.sort_order ASC, ps.created_at ASC").
		Scan(&rows).Error
	if err != nil {
		log.Printf("Error batch getting posts by snippet IDs: %v", err)
		return result
	}
	for _, r := range rows {
		result[r.SnippetID] = append(result[r.SnippetID], models.PostBrief{ID: r.PostID, Title: r.Title})
	}
	return result
}

// GetPostIDsBySnippetID 获取片段关联的文章 ID 列表（后台编辑用）
func GetPostIDsBySnippetID(snippetID uint) ([]uint, error) {
	var ids []uint
	err := config.DB.Model(&models.PostSnippet{}).
		Where("snippet_id = ?", snippetID).
		Order("sort_order ASC, created_at ASC").
		Pluck("post_id", &ids).Error
	if err != nil {
		log.Printf("Error getting post IDs by snippet ID: %v", err)
		return nil, err
	}
	return ids, nil
}
