package recipe

import (
	"context"
	"errors"
	"fmt"

	"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
	"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
	"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"

	"gorm.io/gorm"
)

// 定义领域特定的错误
var (
	ErrPigBreedInUse    = fmt.Errorf("猪品种正在被猪类型使用，无法删除")
	ErrPigBreedNotFound = fmt.Errorf("猪品种不存在")
)

// PigBreedService 定义了猪品种领域的核心业务服务接口
type PigBreedService interface {
	CreatePigBreed(ctx context.Context, breed *models.PigBreed) error
	GetPigBreedByID(ctx context.Context, id uint32) (*models.PigBreed, error)
	UpdatePigBreed(ctx context.Context, breed *models.PigBreed) error
	DeletePigBreed(ctx context.Context, id uint32) error
	ListPigBreeds(ctx context.Context, opts repository.PigBreedListOptions, page, pageSize int) ([]models.PigBreed, int64, error)
}

// pigBreedServiceImpl 是 PigBreedService 的实现
type pigBreedServiceImpl struct {
	ctx         context.Context
	pigTypeRepo repository.PigTypeRepository // PigBreed 相关的操作目前在 PigTypeRepository 中
}

// NewPigBreedService 创建一个新的 PigBreedService 实例
func NewPigBreedService(ctx context.Context, pigTypeRepo repository.PigTypeRepository) PigBreedService {
	return &pigBreedServiceImpl{
		ctx:         ctx,
		pigTypeRepo: pigTypeRepo,
	}
}

// CreatePigBreed 实现了创建猪品种的核心业务逻辑
func (s *pigBreedServiceImpl) CreatePigBreed(ctx context.Context, breed *models.PigBreed) error {
	serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreatePigBreed")
	if err := s.pigTypeRepo.CreatePigBreed(serviceCtx, breed); err != nil {
		return fmt.Errorf("创建猪品种失败: %w", err)
	}
	return nil
}

// GetPigBreedByID 实现了获取单个猪品种的逻辑
func (s *pigBreedServiceImpl) GetPigBreedByID(ctx context.Context, id uint32) (*models.PigBreed, error) {
	serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetPigBreedByID")
	breed, err := s.pigTypeRepo.GetPigBreedByID(serviceCtx, id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, ErrPigBreedNotFound
		}
		return nil, fmt.Errorf("获取猪品种失败: %w", err)
	}
	return breed, nil
}

// UpdatePigBreed 实现了更新猪品种的核心业务逻辑
func (s *pigBreedServiceImpl) UpdatePigBreed(ctx context.Context, breed *models.PigBreed) error {
	serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePigBreed")
	if err := s.pigTypeRepo.UpdatePigBreed(serviceCtx, breed); err != nil {
		return fmt.Errorf("更新猪品种失败: %w", err)
	}
	return nil
}

// DeletePigBreed 实现了删除猪品种的核心业务逻辑
func (s *pigBreedServiceImpl) DeletePigBreed(ctx context.Context, id uint32) error {
	serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeletePigBreed")

	// 检查是否有猪类型关联到该品种
	opts := repository.PigTypeListOptions{BreedID: &id}
	pigTypes, _, err := s.pigTypeRepo.ListPigTypes(serviceCtx, opts, 1, 1) // 只需检查是否存在，所以取1条
	if err != nil {
		return fmt.Errorf("检查猪品种关联失败: %w", err)
	}
	if len(pigTypes) > 0 {
		return ErrPigBreedInUse
	}

	// 检查实体是否存在
	_, err = s.pigTypeRepo.GetPigBreedByID(serviceCtx, id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return ErrPigBreedNotFound
		}
		return fmt.Errorf("获取待删除的猪品种失败: %w", err)
	}

	if err := s.pigTypeRepo.DeletePigBreed(serviceCtx, id); err != nil {
		return fmt.Errorf("删除猪品种失败: %w", err)
	}
	return nil
}

// ListPigBreeds 实现了列出猪品种的逻辑
func (s *pigBreedServiceImpl) ListPigBreeds(ctx context.Context, opts repository.PigBreedListOptions, page, pageSize int) ([]models.PigBreed, int64, error) {
	serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigBreeds")
	breeds, total, err := s.pigTypeRepo.ListPigBreeds(serviceCtx, opts, page, pageSize)
	if err != nil {
		return nil, 0, fmt.Errorf("获取猪品种列表失败: %w", err)
	}
	return breeds, total, nil
}
