package usecase

import (
	"context"
	"strings"

	"haixun-backend/internal/library/clock"
	app "haixun-backend/internal/library/errors"
	"haixun-backend/internal/library/errors/code"
	"haixun-backend/internal/model/copy_draft/domain/entity"
	domrepo "haixun-backend/internal/model/copy_draft/domain/repository"
	domusecase "haixun-backend/internal/model/copy_draft/domain/usecase"

	"github.com/google/uuid"
)

type copyDraftUseCase struct {
	repo domrepo.Repository
}

func NewUseCase(repo domrepo.Repository) domusecase.UseCase {
	return &copyDraftUseCase{repo: repo}
}

func (u *copyDraftUseCase) Create(ctx context.Context, req domusecase.CreateRequest) (*domusecase.CopyDraftSummary, error) {
	if err := requireActor(req.TenantID, req.OwnerUID, req.PersonaID); err != nil {
		return nil, err
	}
	text := strings.TrimSpace(req.Text)
	if text == "" {
		return nil, app.For(code.Persona).InputMissingRequired("draft text is required")
	}
	draftType := strings.TrimSpace(req.DraftType)
	if draftType == "" {
		draftType = entity.DraftTypeViralReplica
	}
	item := &entity.CopyDraft{
		ID:             uuid.NewString(),
		TenantID:       req.TenantID,
		OwnerUID:       req.OwnerUID,
		PersonaID:      req.PersonaID,
		ScanPostID:     strings.TrimSpace(req.ScanPostID),
		DraftType:      draftType,
		Text:           text,
		Angle:          strings.TrimSpace(req.Angle),
		Hook:           strings.TrimSpace(req.Hook),
		Rationale:      strings.TrimSpace(req.Rationale),
		ReferenceNotes: strings.TrimSpace(req.ReferenceNotes),
		Sources:        req.Sources,
		Status:         "pending",
		CreateAt:       clock.NowUnixNano(),
	}
	if err := u.repo.Create(ctx, item); err != nil {
		return nil, err
	}
	summary := toSummary(*item)
	return &summary, nil
}

func (u *copyDraftUseCase) List(ctx context.Context, tenantID, ownerUID, personaID string, limit int) ([]domusecase.CopyDraftSummary, error) {
	if err := requireActor(tenantID, ownerUID, personaID); err != nil {
		return nil, err
	}
	items, err := u.repo.List(ctx, tenantID, ownerUID, personaID, limit)
	if err != nil {
		return nil, err
	}
	out := make([]domusecase.CopyDraftSummary, 0, len(items))
	for _, item := range items {
		out = append(out, toSummary(item))
	}
	return out, nil
}

func requireActor(tenantID, ownerUID, personaID string) error {
	if strings.TrimSpace(tenantID) == "" || strings.TrimSpace(ownerUID) == "" {
		return app.For(code.Auth).AuthUnauthorized("missing actor")
	}
	if strings.TrimSpace(personaID) == "" {
		return app.For(code.Persona).InputMissingRequired("persona_id is required")
	}
	return nil
}

func toSummary(item entity.CopyDraft) domusecase.CopyDraftSummary {
	return domusecase.CopyDraftSummary{
		ID:             item.ID,
		PersonaID:      item.PersonaID,
		ScanPostID:     item.ScanPostID,
		DraftType:      item.DraftType,
		Text:           item.Text,
		Angle:          item.Angle,
		Hook:           item.Hook,
		Rationale:      item.Rationale,
		ReferenceNotes: item.ReferenceNotes,
		Sources:        item.Sources,
		Status:         item.Status,
		CreateAt:       item.CreateAt,
	}
}
