package repositories

import (
	"log"
	"time"

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

// GetSnippets 获取所有代码片段
func GetSnippets() ([]models.Snippet, error) {
	var snippets []models.Snippet
	err := config.DB.Model(&models.Snippet{}).
		Where("deleted_at = ?", 0).
		Order("created_at DESC").
		Find(&snippets).Error
	if err != nil {
		log.Printf("Error querying snippets: %v", err)
		return nil, err
	}
	return snippets, nil
}

// GetSnippetByID 根据ID获取代码片段
func GetSnippetByID(id uint) (*models.Snippet, error) {
	var snippet models.Snippet
	err := config.DB.Model(&models.Snippet{}).
		Where("id = ? AND deleted_at = ?", id, 0).
		First(&snippet).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		log.Printf("Error getting snippet by ID: %v", err)
		return nil, err
	}

	// 更新查看次数
	config.DB.Model(&models.Snippet{}).
		Where("id = ?", id).
		UpdateColumn("view_count", gorm.Expr("view_count + ?", 1))

	return &snippet, nil
}

// BuildSnippetResponse 构建代码片段响应
func BuildSnippetResponse(snippet *models.Snippet) *models.SnippetResponse {
	return BuildSnippetResponseWithPosts(snippet, nil)
}

func BuildSnippetResponseWithPosts(snippet *models.Snippet, posts []models.PostBrief) *models.SnippetResponse {
	resp := &models.SnippetResponse{
		ID:          snippet.ID,
		Title:       snippet.Title,
		Code:        snippet.Code,
		Type:        snippet.Type,
		CodeTypeID:  snippet.CodeTypeID,
		Description: snippet.Description,
		ViewCount:   snippet.ViewCount,
	}
	if ct := GetCodeTypeForSnippet(snippet); ct != nil {
		r := BuildCodeTypeResponse(ct)
		resp.CodeType = &r
		if resp.Type == "" {
			resp.Type = ct.Name
		}
	}
	if posts != nil {
		resp.Posts = posts
	} else if posts, err := GetPostsBySnippetID(snippet.ID); err == nil && len(posts) > 0 {
		resp.Posts = posts
	}
	return resp
}

// BuildSnippetsResponse 构建代码片段列表响应
func BuildSnippetsResponse(snippets []models.Snippet) []models.SnippetResponse {
	if len(snippets) == 0 {
		return []models.SnippetResponse{}
	}
	ids := make([]uint, len(snippets))
	for i, s := range snippets {
		ids[i] = s.ID
	}
	postsMap := GetPostsBySnippetIDs(ids)
	var responses []models.SnippetResponse
	for _, snippet := range snippets {
		responses = append(responses, *BuildSnippetResponseWithPosts(&snippet, postsMap[snippet.ID]))
	}
	return responses
}

// CreateSnippet 创建代码片段
func CreateSnippet(snippet *models.Snippet) error {
	err := config.DB.Create(snippet).Error
	if err != nil {
		log.Printf("Error creating snippet: %v", err)
		return err
	}
	return nil
}

// UpdateSnippet 更新代码片段
func UpdateSnippet(snippet *models.Snippet) error {
	err := config.DB.Model(&models.Snippet{}).
		Where("id = ? AND deleted_at = ?", snippet.ID, 0).
		Updates(map[string]interface{}{
			"title":        snippet.Title,
			"code":         snippet.Code,
			"type":         snippet.Type,
			"code_type_id": snippet.CodeTypeID,
			"description":  snippet.Description,
			"updated_at":   time.Now().Unix(),
		}).Error
	if err != nil {
		log.Printf("Error updating snippet: %v", err)
		return err
	}
	return nil
}

// DeleteSnippet 删除代码片段 (Soft Delete)
func DeleteSnippet(id uint) error {
	err := config.DB.Model(&models.Snippet{}).
		Where("id = ?", id).
		Update("deleted_at", time.Now().Unix()).Error
	if err != nil {
		log.Printf("Error deleting snippet: %v", err)
		return err
	}
	return nil
}

// AdminSnippetFilter 后台代码片段筛选
type AdminSnippetFilter struct {
	Keyword    string
	CodeTypeID uint
}

// GetAdminSnippets 获取后台代码片段列表 (分页)
func GetAdminSnippets(page, pageSize int, filter AdminSnippetFilter) ([]models.Snippet, int, error) {
	offset := (page - 1) * pageSize

	var snippets []models.Snippet
	var total int64

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

	if filter.Keyword != "" {
		like := "%" + filter.Keyword + "%"
		query = query.Where("title LIKE ?", like)
	}
	if filter.CodeTypeID > 0 {
		query = query.Where("code_type_id = ?", filter.CodeTypeID)
	}

	err := query.Count(&total).Error
	if err != nil {
		log.Printf("Error getting snippet count: %v", err)
		return nil, 0, err
	}

	// 获取列表
	err = query.
		Order("created_at DESC").
		Limit(pageSize).
		Offset(offset).
		Find(&snippets).Error
	if err != nil {
		log.Printf("Error querying admin snippets: %v", err)
		return nil, 0, err
	}

	return snippets, int(total), nil
}
