<?php

namespace App\Filament\Resources\Learning\Assignments\Pages;

use App\Enums\AssignmentType;
use App\Filament\Actions\BackAction;
use App\Filament\Resources\Learning\Assignments\AssignmentResource;
use App\Filament\Support\SystemNotification;
use App\Models\Assignment;
use App\Models\AssignmentSubmission;
use App\Models\Student;
use App\Models\StudyGroup;
use Filament\Resources\Pages\Page;
use Livewire\Attributes\Computed;
use Livewire\WithFileUploads;

class SubmitAssignmentPage extends Page
{
    use WithFileUploads;

    protected static string $resource = AssignmentResource::class;

    protected string $view = 'filament.resources.learning.assignments.pages.submit-assignment';

    protected static ?string $title = 'Kumpulkan Tugas';

    public Assignment $record;

    public $file = null;

    #[Computed]
    public function statusCards(): array
    {
        return [
            [
                'label' => 'Batas Waktu',
                'value' => $this->record->due_date?->translatedFormat('l, d F Y, H:i'),
                'icon' => 'heroicon-o-clock',
                'is_danger' => $this->isOverdue,
                'badge' => $this->isOverdue ? '(Terlewat)' : null,
            ],
            [
                'label' => 'Status Pengumpulan',
                'value' => $this->isOverdue ? 'Ditutup' : 'Terbuka',
                'icon' => $this->isOverdue ? 'heroicon-o-lock-closed' : 'heroicon-o-check-circle',
                'is_danger' => $this->isOverdue,
                'is_success' => ! $this->isOverdue,
            ],
        ];
    }

    #[Computed]
    public function student(): Student
    {
        return auth()->user()->student;
    }

    #[Computed]
    public function currentGroup(): ?StudyGroup
    {
        $student = $this->student;

        return $this->record->studyGroups()
            ->whereHas('students', fn ($q) => $q->whereKey($student->id))
            ->first();
    }

    #[Computed]
    public function existingSubmission(): ?AssignmentSubmission
    {
        $student = $this->student;

        if ($this->record->type === AssignmentType::Group) {
            $group = $this->currentGroup;
            if (! $group) {
                return null;
            }

            return AssignmentSubmission::where('assignment_id', $this->record->id)
                ->where('study_group_id', $group->id)
                ->first();
        }

        return AssignmentSubmission::where('assignment_id', $this->record->id)
            ->where('student_id', $student->id)
            ->first();
    }

    #[Computed]
    public function isResubmit(): bool
    {
        return $this->existingSubmission !== null;
    }

    #[Computed]
    public function isOverdue(): bool
    {
        return now()->isAfter($this->record->due_date);
    }

    #[Computed]
    public function canSubmit(): bool
    {
        if ($this->record->type === AssignmentType::Individual) {
            return true;
        }

        $group = $this->currentGroup;

        return $group && $group->leader_id === $this->student->id;
    }

    #[Computed]
    public function submissionStatus(): object
    {
        $existing = $this->existingSubmission;

        if ($this->isResubmit) {
            return (object) [
                'type' => 'submitted',
                'badge_color' => 'success',
                'badge_label' => 'Sudah Dikumpulkan',
            ];
        }

        return (object) [
            'type' => 'none',
            'badge_color' => 'danger',
            'badge_label' => 'Tidak Mengumpulkan',
        ];
    }

    public function getSubmissionFileUrl(): ?string
    {
        return $this->existingSubmission?->getFirstMediaUrl('submission');
    }

    public function submit(): void
    {
        $student = $this->student;
        $assignment = $this->record;

        if ($assignment->type === AssignmentType::Group && ! $this->currentGroup) {
            SystemNotification::danger(
                'Gagal Mengumpulkan 🚫',
                'Anda tidak terdaftar dalam kelompok manapun yang ditugaskan untuk tugas ini.'
            )->send();

            return;
        }

        if (! $this->canSubmit) {
            SystemNotification::danger(
                'Gagal Mengumpulkan 🚫',
                'Hanya ketua kelompok yang diizinkan untuk mengumpulkan atau memperbarui tugas kelompok.'
            )->send();

            return;
        }

        $existingSubmission = $this->existingSubmission;

        if (! $existingSubmission && ! $this->file) {
            SystemNotification::warning(
                'File Diperlukan',
                'Silakan pilih file untuk dikumpulkan.'
            )->send();

            return;
        }

        $this->validate([
            'file' => [
                'nullable',
                'file',
                'max:'.(1024 * 5),
                'mimes:pdf',
            ],
        ], [
            'file.max' => 'Ukuran file maksimal 5MB.',
            'file.mimes' => 'Hanya file PDF yang diizinkan.',
        ]);

        if ($existingSubmission) {
            if ($this->file) {
                $existingSubmission->clearMediaCollection('submission');
                $existingSubmission->addMedia($this->file->getRealPath())
                    ->usingName($this->file->getClientOriginalName())
                    ->usingFileName($this->file->getClientOriginalName())
                    ->toMediaCollection('submission');
            }

            $existingSubmission->update([
                'submitted_at' => now(),
            ]);

            SystemNotification::success(
                'Tugas Diperbarui ✅',
                'File tugas Anda telah berhasil diunggah ulang dan diperbarui.'
            )->send();
        } else {
            $submission = AssignmentSubmission::create([
                'assignment_id' => $assignment->id,
                'student_id' => $student->id,
                'study_group_id' => $assignment->type === AssignmentType::Group ? $this->currentGroup?->id : null,
                'submitted_at' => now(),
            ]);

            $submission->addMedia($this->file->getRealPath())
                ->usingName($this->file->getClientOriginalName())
                ->usingFileName($this->file->getClientOriginalName())
                ->toMediaCollection('submission');

            SystemNotification::success(
                'Tugas Dikumpulkan 🚀',
                'Berhasil! Tugas Anda telah tercatat di sistem.'
            )->send();
        }

        $this->file = null;
        unset($this->existingSubmission, $this->isResubmit);
    }

    protected function getHeaderActions(): array
    {
        return [
            BackAction::make()
                ->url(AssignmentResource::getUrl()),
        ];
    }
}
