package processor

import (
	"context"

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

	"github.com/google/uuid"
)

type ActivityLogProcessorImpl struct {
	repo *repository.LetterIncomingActivityLogRepository
}

func NewActivityLogProcessor(repo *repository.LetterIncomingActivityLogRepository) *ActivityLogProcessorImpl {
	return &ActivityLogProcessorImpl{repo: repo}
}

func (p *ActivityLogProcessorImpl) Log(ctx context.Context, letterID uuid.UUID, actionType string, actorUserID *uuid.UUID, actorDepartmentID *uuid.UUID, targetType *string, targetID *uuid.UUID, fromStatus *string, toStatus *string, contextData map[string]interface{}) error {
	ctxJSON := entities.JSONB{}
	for k, v := range contextData {
		ctxJSON[k] = v
	}
	entry := &entities.LetterIncomingActivityLog{
		LetterID:          letterID,
		ActionType:        actionType,
		ActorUserID:       actorUserID,
		ActorDepartmentID: actorDepartmentID,
		TargetType:        targetType,
		TargetID:          targetID,
		FromStatus:        fromStatus,
		ToStatus:          toStatus,
		Context:           ctxJSON,
	}
	return p.repo.Create(ctx, entry)
}

func (p *ActivityLogProcessorImpl) LogLetterDispositionStatusUpdate(ctx context.Context, letterID uuid.UUID, userID uuid.UUID, status string) error {
	return p.Log(ctx, letterID, "disposition_status_update", &userID, nil, nil, nil, nil, &status, map[string]interface{}{
		"status": status,
	})
}

func (p *ActivityLogProcessorImpl) LogLetterCreated(ctx context.Context, letterID uuid.UUID, userID uuid.UUID, letterNumber string) error {
	return p.Log(ctx, letterID, "letter.created", &userID, nil, nil, nil, nil, nil, map[string]interface{}{
		"letter_number": letterNumber,
	})
}

func (p *ActivityLogProcessorImpl) LogAttachmentUploaded(ctx context.Context, letterID uuid.UUID, userID uuid.UUID, fileName string, fileType string) error {
	return p.Log(ctx, letterID, "attachment.uploaded", &userID, nil, nil, nil, nil, nil, map[string]interface{}{
		"file_name": fileName,
		"file_type": fileType,
	})
}

func (p *ActivityLogProcessorImpl) LogDispositionCreated(ctx context.Context, letterID uuid.UUID, userID uuid.UUID, departmentCount int) error {
	return p.Log(ctx, letterID, "disposition.created", &userID, nil, nil, nil, nil, nil, map[string]interface{}{
		"department_count": departmentCount,
	})
}
