<?php

namespace App\Services\Administrator;

use App\Mail\TeacherSubmissionReminderMail;
use App\Models\ClassSection;
use App\Models\TeacherSubmissionNotificationHistory;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;

class TeacherSubmissionNotificationService
{
    public function __construct(
        protected AdministratorSharedService $shared,
        protected TeacherSubmissionSupportService $support
    ) {
    }

    public function send(Request $request, int $adminId): array
    {
        $notify = $request->input('notify');
        if (!is_array($notify)) {
            return [
                'success' => false,
                'message' => 'Select at least one teacher to notify.',
                'status' => 422,
            ];
        }

        $missingItemsPayload = $request->input('missing_items', []);
        $targets = $this->extractTargets($notify);

        if (empty($targets)) {
            return [
                'success' => false,
                'message' => 'Select at least one teacher to notify.',
                'status' => 422,
            ];
        }

        $teacherIds = array_values(array_unique(array_column($targets, 'teacher_id')));
        $classSectionIds = array_values(array_unique(array_column($targets, 'class_section_id')));

        $classSections = ClassSection::query()
            ->select('class_section_id', 'class_section_name')
            ->whereIn('class_section_id', $classSectionIds)
            ->get()
            ->keyBy('class_section_id');

        $teachers = User::query()
            ->select('id', 'firstname', 'lastname', 'email')
            ->whereIn('id', $teacherIds)
            ->get()
            ->keyBy('id');

        $adminUser = User::find($adminId);
        $adminName = trim(($adminUser->firstname ?? '') . ' ' . ($adminUser->lastname ?? '')) ?: 'Administrator';

        $scoreUrl = url('/');
        $sentCount = 0;
        $failCount = 0;

        foreach ($targets as $target) {
            $classSectionId = (int) $target['class_section_id'];
            $teacherId = (int) $target['teacher_id'];

            $teacher = $teachers->get($teacherId);
            $sectionName = $classSections->get($classSectionId)?->class_section_name ?? "Section {$classSectionId}";
            $teacherName = trim(($teacher->firstname ?? '') . ' ' . ($teacher->lastname ?? '')) ?: 'Teacher';

            $missingPayload = $missingItemsPayload[$classSectionId][$teacherId] ?? '';
            $missingItems = $this->support->parseMissingItemsPayload((string) $missingPayload);

            $missingNote = !empty($missingItems)
                ? '<p>Outstanding items: ' . e($this->support->formatMissingItemsText($missingItems)) . '.</p>'
                : '<p>Our records show no outstanding submissions for this section, but please verify if anything still needs attention.</p>';

            $subject = "Reminder: Complete submissions for {$sectionName}";
            $body = "<p>Dear {$teacherName},</p>"
                . "<p>Administration is gently reminding you to wrap up any remaining score submissions and/or comments for {$sectionName}.</p>"
                . $missingNote
                . "<p>Visit <a href=\"{$scoreUrl}\">Teacher Score Submission</a> to address any remaining items.</p>"
                . "<p>Thank you,<br>{$adminName}</p>";

            $email = $teacher->email ?? '';
            $status = 'failed';

            if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
                try {
                    Mail::to($email)->send(new TeacherSubmissionReminderMail($subject, $body));
                    $status = 'sent';
                } catch (\Throwable $e) {
                    Log::error('Teacher submission notification failed: ' . $e->getMessage());
                }
            }

            if ($status === 'sent') {
                $sentCount++;
            } else {
                $failCount++;
            }

            TeacherSubmissionNotificationHistory::create([
                'teacher_id' => $teacherId,
                'class_section_id' => $classSectionId,
                'admin_id' => $adminId,
                'notification_category' => 'teacher_submissions',
                'message' => $this->support->truncateNotificationMessage($body),
                'status' => $status,
                'school_year' => $this->shared->getSchoolYear(),
                'semester' => $this->shared->getSemester(),
                'sent_at' => now(),
            ]);
        }

        $parts = [];
        if ($sentCount > 0) {
            $parts[] = $sentCount . ' reminder' . ($sentCount === 1 ? '' : 's') . ' sent';
        }
        if ($failCount > 0) {
            $parts[] = $failCount . ' reminder' . ($failCount === 1 ? '' : 's') . ' failed';
        }

        return [
            'success' => $failCount === 0,
            'message' => !empty($parts) ? implode(' and ', $parts) : 'No notifications were sent.',
            'sent' => $sentCount,
            'failed' => $failCount,
            'status' => $failCount === 0 ? 200 : 207,
        ];
    }

    protected function extractTargets(array $notify): array
    {
        $targets = [];

        foreach ($notify as $sectionIdRaw => $teachers) {
            $sectionId = (int) $sectionIdRaw;
            if ($sectionId <= 0 || !is_array($teachers)) {
                continue;
            }

            foreach ($teachers as $teacherIdRaw => $value) {
                $teacherId = (int) $teacherIdRaw;
                if ($teacherId <= 0 || $value === null || $value === '') {
                    continue;
                }

                $targets["{$sectionId}_{$teacherId}"] = [
                    'class_section_id' => $sectionId,
                    'teacher_id' => $teacherId,
                ];
            }
        }

        return array_values($targets);
    }
}
