package processor

import (
	"context"

	"eslogad-be/internal/entities"
	"eslogad-be/internal/repository"

	"github.com/google/uuid"
)

type LetterCreationProcessor interface {
	PrepareLetterForCreation(ctx context.Context, letter *entities.LetterOutgoing, departmentID uuid.UUID) error
	CreateLetter(ctx context.Context, letter *entities.LetterOutgoing) error
	GenerateLetterNumber(ctx context.Context, letter *entities.LetterOutgoing) error
}

type LetterCreationProcessorImpl struct {
	letterRepo       *repository.LetterOutgoingRepository
	approvalFlowRepo *repository.ApprovalFlowRepository
	numberGenerator  LetterNumberGenerator
}

func NewLetterCreationProcessor(
	letterRepo *repository.LetterOutgoingRepository,
	approvalFlowRepo *repository.ApprovalFlowRepository,
	numberGenerator LetterNumberGenerator,
) *LetterCreationProcessorImpl {
	return &LetterCreationProcessorImpl{
		letterRepo:       letterRepo,
		approvalFlowRepo: approvalFlowRepo,
		numberGenerator:  numberGenerator,
	}
}

func (p *LetterCreationProcessorImpl) PrepareLetterForCreation(ctx context.Context, letter *entities.LetterOutgoing, departmentID uuid.UUID) error {
	// Assign approval flow from department if not provided
	if letter.ApprovalFlowID == nil && departmentID != uuid.Nil {
		flow, err := p.approvalFlowRepo.GetByDepartment(ctx, departmentID)
		if err == nil && flow != nil {
			letter.ApprovalFlowID = &flow.ID
		}
	}

	// Set initial status based on approval flow
	if letter.ApprovalFlowID != nil {
		letter.Status = entities.LetterOutgoingStatusPendingApproval
	} else {
		letter.Status = entities.LetterOutgoingStatusApproved
	}

	return nil
}

func (p *LetterCreationProcessorImpl) CreateLetter(ctx context.Context, letter *entities.LetterOutgoing) error {
	return p.letterRepo.Create(ctx, letter)
}

func (p *LetterCreationProcessorImpl) GenerateLetterNumber(ctx context.Context, letter *entities.LetterOutgoing) error {
	letterNumber, err := p.numberGenerator.GenerateNumber(
		ctx,
		"outgoing_letter_prefix",
		"outgoing_letter_sequence",
		"ESLO",
	)
	if err != nil {
		return err
	}

	letter.LetterNumber = letterNumber
	return nil
}