package repositories

import (
	"log"
	"time"

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

func GetCodeTypes() ([]models.CodeType, error) {
	var list []models.CodeType
	err := config.DB.Model(&models.CodeType{}).
		Where("deleted_at = ?", 0).
		Order("category ASC, name ASC").
		Find(&list).Error
	return list, err
}

func GetCodeTypeByID(id uint) (*models.CodeType, error) {
	var ct models.CodeType
	err := config.DB.Model(&models.CodeType{}).
		Where("id = ? AND deleted_at = ?", id, 0).
		First(&ct).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, err
	}
	return &ct, nil
}

func CreateCodeType(ct *models.CodeType) error {
	return config.DB.Create(ct).Error
}

func UpdateCodeType(ct *models.CodeType) error {
	return config.DB.Model(&models.CodeType{}).
		Where("id = ? AND deleted_at = ?", ct.ID, 0).
		Updates(map[string]interface{}{
			"name":       ct.Name,
			"category":   ct.Category,
			"updated_at": time.Now().Unix(),
		}).Error
}

func DeleteCodeType(id uint) error {
	return config.DB.Model(&models.CodeType{}).
		Where("id = ?", id).
		Update("deleted_at", time.Now().Unix()).Error
}

func CountSnippetsByCodeTypeID(id uint) (int64, error) {
	var count int64
	err := config.DB.Model(&models.Snippet{}).
		Where("code_type_id = ? AND deleted_at = ?", id, 0).
		Count(&count).Error
	return count, err
}

func BuildCodeTypeResponse(ct *models.CodeType) models.CodeTypeResponse {
	return models.CodeTypeResponse{
		ID:       ct.ID,
		Name:     ct.Name,
		Category: ct.Category,
	}
}

func BuildCodeTypesResponse(list []models.CodeType) []models.CodeTypeResponse {
	res := make([]models.CodeTypeResponse, 0, len(list))
	for _, ct := range list {
		res = append(res, BuildCodeTypeResponse(&ct))
	}
	return res
}

func GetCodeTypeForSnippet(snippet *models.Snippet) *models.CodeType {
	if snippet.CodeTypeID == 0 {
		return nil
	}
	ct, err := GetCodeTypeByID(snippet.CodeTypeID)
	if err != nil {
		log.Printf("Error loading code type %d: %v", snippet.CodeTypeID, err)
		return nil
	}
	return ct
}

// GetCodeTypesByIDs 批量获取代码类型
func GetCodeTypesByIDs(ids []uint) map[uint]*models.CodeType {
	result := make(map[uint]*models.CodeType)
	if len(ids) == 0 {
		return result
	}
	unique := make([]uint, 0, len(ids))
	seen := make(map[uint]struct{}, len(ids))
	for _, id := range ids {
		if id == 0 {
			continue
		}
		if _, ok := seen[id]; ok {
			continue
		}
		seen[id] = struct{}{}
		unique = append(unique, id)
	}
	if len(unique) == 0 {
		return result
	}
	var types []models.CodeType
	if err := config.DB.Model(&models.CodeType{}).
		Where("id IN ? AND deleted_at = ?", unique, 0).
		Find(&types).Error; err != nil {
		log.Printf("Error batch loading code types: %v", err)
		return result
	}
	for i := range types {
		result[types[i].ID] = &types[i]
	}
	return result
}
