<?php

namespace App\Services\Promotions;

use App\Models\PromotionAuditLog;
use App\Models\StudentPromotionRecord;

/**
 * Centralised writer for the promotion audit trail (plan section 18).
 */
class PromotionAuditService
{
    public function logRecordCreated(StudentPromotionRecord $record, ?int $userId, ?string $notes = null): PromotionAuditLog
    {
        return $this->log($record, PromotionAuditLog::ACTION_RECORD_CREATED, [
            'user_id' => $userId,
            'new_value' => $record->promotion_status,
            'notes' => $notes,
        ]);
    }

    public function logStatusChange(
        StudentPromotionRecord $record,
        ?string $oldStatus,
        string $newStatus,
        ?int $userId,
        ?string $notes = null
    ): PromotionAuditLog {
        return $this->log($record, PromotionAuditLog::ACTION_STATUS_CHANGED, [
            'user_id' => $userId,
            'field' => 'promotion_status',
            'old_value' => $oldStatus,
            'new_value' => $newStatus,
            'notes' => $notes,
        ]);
    }

    public function logEligibilityEvaluation(
        StudentPromotionRecord $record,
        bool $passed,
        ?int $userId,
        ?string $notes = null
    ): PromotionAuditLog {
        return $this->log($record, PromotionAuditLog::ACTION_ELIGIBILITY_EVALUATED, [
            'user_id' => $userId,
            'field' => 'passed_current_level',
            'new_value' => $passed ? '1' : '0',
            'notes' => $notes,
        ]);
    }

    public function logParentNotified(StudentPromotionRecord $record, ?int $userId, ?string $notes = null): PromotionAuditLog
    {
        return $this->log($record, PromotionAuditLog::ACTION_PARENT_NOTIFIED, [
            'user_id' => $userId,
            'notes' => $notes,
        ]);
    }

    public function logEnrollmentStepCompleted(
        StudentPromotionRecord $record,
        string $field,
        ?int $userId,
        ?string $notes = null
    ): PromotionAuditLog {
        return $this->log($record, PromotionAuditLog::ACTION_ENROLLMENT_STEP_COMPLETED, [
            'user_id' => $userId,
            'field' => $field,
            'new_value' => '1',
            'notes' => $notes,
        ]);
    }

    public function logEnrollmentStarted(StudentPromotionRecord $record, ?int $userId): PromotionAuditLog
    {
        return $this->log($record, PromotionAuditLog::ACTION_ENROLLMENT_STARTED, [
            'user_id' => $userId,
        ]);
    }

    public function logEnrollmentCompleted(StudentPromotionRecord $record, ?int $userId): PromotionAuditLog
    {
        return $this->log($record, PromotionAuditLog::ACTION_ENROLLMENT_COMPLETED, [
            'user_id' => $userId,
        ]);
    }

    public function logPromotionFinalized(StudentPromotionRecord $record, ?int $userId): PromotionAuditLog
    {
        return $this->log($record, PromotionAuditLog::ACTION_PROMOTION_FINALIZED, [
            'user_id' => $userId,
            'new_value' => $record->promotion_status,
        ]);
    }

    public function logDeadlineSet(
        StudentPromotionRecord $record,
        ?string $oldDeadline,
        ?string $newDeadline,
        ?int $userId
    ): PromotionAuditLog {
        return $this->log($record, PromotionAuditLog::ACTION_DEADLINE_SET, [
            'user_id' => $userId,
            'field' => 'enrollment_deadline',
            'old_value' => $oldDeadline,
            'new_value' => $newDeadline,
        ]);
    }

    public function logReminderSent(
        StudentPromotionRecord $record,
        string $reminderType,
        ?int $userId
    ): PromotionAuditLog {
        return $this->log($record, PromotionAuditLog::ACTION_REMINDER_SENT, [
            'user_id' => $userId,
            'field' => 'reminder_type',
            'new_value' => $reminderType,
        ]);
    }

    public function logDeadlineExpired(StudentPromotionRecord $record): PromotionAuditLog
    {
        return $this->log($record, PromotionAuditLog::ACTION_DEADLINE_EXPIRED, []);
    }

    public function logManualOverride(
        StudentPromotionRecord $record,
        string $field,
        ?string $oldValue,
        ?string $newValue,
        ?int $userId,
        ?string $notes = null
    ): PromotionAuditLog {
        return $this->log($record, PromotionAuditLog::ACTION_MANUAL_OVERRIDE, [
            'user_id' => $userId,
            'field' => $field,
            'old_value' => $oldValue,
            'new_value' => $newValue,
            'notes' => $notes,
        ]);
    }

    private function log(StudentPromotionRecord $record, string $action, array $extra): PromotionAuditLog
    {
        return PromotionAuditLog::query()->create(array_merge([
            'promotion_id' => (int) $record->getKey(),
            'student_id' => (int) $record->student_id,
            'action_type' => $action,
            'performed_at' => now(),
        ], $extra));
    }
}
