<?php

namespace App\Filament\Pages;

use App\Enums\DecisionAdmin;
use App\Enums\VerificationStatus;
use App\Filament\Resources\Manage\Journalists\Pages\ManageJournalists;
use App\Models\Company;
use App\Models\Journalist;
use App\Models\PartnerMedia;
use App\Models\VerificationRequest;
use BackedEnum;
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Support\Collection;
use UnitEnum;

class CustomVerification extends Page implements HasActions, HasForms
{
    use HasPageShield, InteractsWithActions, InteractsWithForms;

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-check-badge';

    protected static ?string $title = 'Verifikasi';

    protected static ?string $navigationLabel = 'Verifikasi';

    protected static string|UnitEnum|null $navigationGroup = 'Kelola';

    protected static ?string $slug = 'manage/verification';

    protected static ?int $navigationSort = 12;

    protected string $view = 'filament.pages.verification';

    public ?Company $company = null;

    public ?PartnerMedia $partnerMedia = null;

    public ?Journalist $journalist = null;

    public ?VerificationRequest $companyVerification = null;

    public ?VerificationRequest $mediaVerification = null;

    public ?VerificationRequest $journalistVerification = null;

    public function mount(): void
    {
        $this->company = auth()->user()->company;
        $this->partnerMedia = auth()->user()->company?->partnerMedia;
        $this->journalist = auth()->user()->company?->partnerMedia?->journalists?->first();

        // Load verification requests with reviews
        if ($this->company) {
            $this->companyVerification = $this->company->verificationRequest()
                ->with(['reviews.reviewer'])
                ->latest()
                ->first();
        }

        if ($this->partnerMedia) {
            $this->mediaVerification = $this->partnerMedia->verificationRequest()
                ->with(['reviews.reviewer'])
                ->latest()
                ->first();
        }

        if ($this->journalist) {
            $this->journalistVerification = $this->journalist->verificationRequest()
                ->with(['reviews.reviewer'])
                ->latest()
                ->first();
        }
    }

    /**
     * Determine the current step based on status
     */
    protected function resolveStep(?VerificationStatus $status, bool $hasData = false): int
    {
        if (! $hasData) {
            return 1; // No data yet
        }

        return match ($status) {
            VerificationStatus::PENDING,
            VerificationStatus::NEED_REVISION => 2, // In review or needs revision

            VerificationStatus::APPROVED,
            VerificationStatus::REJECTED => 3, // Final decision

            default => 1, // Draft / not submitted yet
        };
    }

    /**
     * Check if user can submit verification for entity
     */
    protected function canSubmit($entity, ?VerificationRequest $verification): bool
    {
        if (! $entity) {
            return false;
        }

        // No verification yet - can submit
        if (! $verification) {
            return true;
        }

        // Can resubmit only if status is NEED_REVISION
        return $verification->status === VerificationStatus::NEED_REVISION;
    }

    /**
     * Check if entity is approved
     */
    protected function isApproved(?VerificationRequest $verification): bool
    {
        return $verification?->status === VerificationStatus::APPROVED;
    }

    /**
     * Check if entity is rejected
     */
    protected function isRejected(?VerificationRequest $verification): bool
    {
        return $verification?->status === VerificationStatus::REJECTED;
    }

    /**
     * Check if entity is pending review
     */
    protected function isPending(?VerificationRequest $verification): bool
    {
        return $verification?->status === VerificationStatus::PENDING;
    }

    /**
     * Check if entity needs revision
     */
    protected function needsRevision(?VerificationRequest $verification): bool
    {
        return $verification?->status === VerificationStatus::NEED_REVISION;
    }

    /**
     * Get the latest review notes for an entity
     */
    protected function getLatestReviewNotes(?VerificationRequest $verification): ?string
    {
        if (! $verification) {
            return null;
        }

        $latestReview = $verification->reviews()
            ->whereIn('decision', [DecisionAdmin::NEED_REVISION, DecisionAdmin::REJECTED])
            ->latest()
            ->first();

        return $latestReview?->note;
    }

    /**
     * Get all reviews history for an entity
     */
    protected function getReviewHistory(?VerificationRequest $verification): Collection
    {
        if (! $verification) {
            return collect();
        }

        return $verification->reviews()
            ->with('reviewer')
            ->latest()
            ->get();
    }

    public function companyProgress(): array
    {
        $hasData = $this->company !== null;
        $currentStep = $this->resolveStep($this->companyVerification?->status, $hasData);

        return [
            'title' => 'Perusahaan',
            'description' => 'Progress verifikasi perusahaan',
            'icon' => 'heroicon-o-building-office-2',
            'currentStep' => $currentStep,
            'entity' => $this->company,
            'verification' => $this->companyVerification,
            'canSubmit' => $this->canSubmit($this->company, $this->companyVerification),
            'isApproved' => $this->isApproved($this->companyVerification),
            'isRejected' => $this->isRejected($this->companyVerification),
            'isPending' => $this->isPending($this->companyVerification),
            'needsRevision' => $this->needsRevision($this->companyVerification),
            'latestNotes' => $this->getLatestReviewNotes($this->companyVerification),
            'reviewHistory' => $this->getReviewHistory($this->companyVerification),
            'editUrl' => CustomCompany::getUrl(),
            'steps' => [
                [
                    'title' => 'Pengajuan',
                    'description' => $hasData ? 'Data perusahaan sudah diisi' : 'Lengkapi data perusahaan',
                ],
                [
                    'title' => 'Verifikasi',
                    'description' => match ($this->companyVerification?->status) {
                        VerificationStatus::NEED_REVISION => 'Perlu perbaikan data',
                        VerificationStatus::PENDING => 'Sedang diverifikasi admin',
                        default => 'Menunggu pengajuan',
                    },
                ],
                [
                    'title' => 'Selesai',
                    'description' => match ($this->companyVerification?->status) {
                        VerificationStatus::APPROVED => 'Perusahaan disetujui',
                        VerificationStatus::REJECTED => 'Perusahaan ditolak',
                        default => 'Menunggu keputusan',
                    },
                ],
            ],
        ];
    }

    public function mediaProgress(): array
    {
        $hasData = $this->partnerMedia !== null;
        $currentStep = $this->resolveStep($this->mediaVerification?->status, $hasData);

        return [
            'title' => 'Media',
            'description' => 'Progress verifikasi media',
            'currentStep' => $currentStep,
            'entity' => $this->partnerMedia,
            'verification' => $this->mediaVerification,
            'canSubmit' => $this->canSubmit($this->partnerMedia, $this->mediaVerification),
            'isApproved' => $this->isApproved($this->mediaVerification),
            'isRejected' => $this->isRejected($this->mediaVerification),
            'isPending' => $this->isPending($this->mediaVerification),
            'needsRevision' => $this->needsRevision($this->mediaVerification),
            'latestNotes' => $this->getLatestReviewNotes($this->mediaVerification),
            'reviewHistory' => $this->getReviewHistory($this->mediaVerification),
            'editUrl' => CustomMedia::getUrl(),
            'steps' => [
                [
                    'title' => 'Pengajuan',
                    'description' => $hasData ? 'Data media sudah diisi' : 'Lengkapi data media',
                ],
                [
                    'title' => 'Verifikasi',
                    'description' => match ($this->mediaVerification?->status) {
                        VerificationStatus::NEED_REVISION => 'Perlu perbaikan data',
                        VerificationStatus::PENDING => 'Sedang diverifikasi admin',
                        default => 'Menunggu pengajuan',
                    },
                ],
                [
                    'title' => 'Selesai',
                    'description' => match ($this->mediaVerification?->status) {
                        VerificationStatus::APPROVED => 'Media disetujui',
                        VerificationStatus::REJECTED => 'Media ditolak',
                        default => 'Menunggu keputusan',
                    },
                ],
            ],
        ];
    }

    public function journalistProgress(): array
    {
        $hasData = $this->journalist !== null;
        $currentStep = $this->resolveStep($this->journalistVerification?->status, $hasData);

        return [
            'title' => 'Jurnalis',
            'description' => 'Progress verifikasi jurnalis',
            'currentStep' => $currentStep,
            'entity' => $this->journalist,
            'verification' => $this->journalistVerification,
            'canSubmit' => $this->canSubmit($this->journalist, $this->journalistVerification),
            'isApproved' => $this->isApproved($this->journalistVerification),
            'isRejected' => $this->isRejected($this->journalistVerification),
            'isPending' => $this->isPending($this->journalistVerification),
            'needsRevision' => $this->needsRevision($this->journalistVerification),
            'latestNotes' => $this->getLatestReviewNotes($this->journalistVerification),
            'reviewHistory' => $this->getReviewHistory($this->journalistVerification),
            'editUrl' => ManageJournalists::getUrl(),
            'steps' => [
                [
                    'title' => 'Pengajuan',
                    'description' => $hasData ? 'Data jurnalis sudah diisi' : 'Lengkapi data jurnalis',
                ],
                [
                    'title' => 'Verifikasi',
                    'description' => match ($this->journalistVerification?->status) {
                        VerificationStatus::NEED_REVISION => 'Perlu perbaikan data',
                        VerificationStatus::PENDING => 'Sedang diverifikasi admin',
                        default => 'Menunggu pengajuan',
                    },
                ],
                [
                    'title' => 'Selesai',
                    'description' => match ($this->journalistVerification?->status) {
                        VerificationStatus::APPROVED => 'Jurnalis disetujui',
                        VerificationStatus::REJECTED => 'Jurnalis ditolak',
                        default => 'Menunggu keputusan',
                    },
                ],
            ],
        ];
    }

    /**
     * Submit company verification action
     */
    public function submitCompanyAction(): Action
    {
        return Action::make('submitCompany')
            ->label(fn () => $this->needsRevision($this->companyVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi')
            ->icon('heroicon-o-paper-airplane')
            ->color('primary')
            ->requiresConfirmation()
            ->modalHeading('Ajukan Verifikasi Perusahaan')
            ->modalDescription('Apakah Anda yakin ingin mengajukan data perusahaan untuk diverifikasi? Pastikan semua data sudah benar.')
            ->modalSubmitActionLabel('Ya, Ajukan')
            ->visible(fn () => $this->canSubmit($this->company, $this->companyVerification))
            ->action(function () {
                $this->submitVerification('company', $this->company, $this->companyVerification);
            });
    }

    /**
     * Submit media verification action
     */
    public function submitMediaAction(): Action
    {
        return Action::make('submitMedia')
            ->label(fn () => $this->needsRevision($this->mediaVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi')
            ->icon('heroicon-o-paper-airplane')
            ->color('primary')
            ->requiresConfirmation()
            ->modalHeading('Ajukan Verifikasi Media')
            ->modalDescription('Apakah Anda yakin ingin mengajukan data media untuk diverifikasi? Pastikan semua data sudah benar.')
            ->modalSubmitActionLabel('Ya, Ajukan')
            ->visible(fn () => $this->canSubmit($this->partnerMedia, $this->mediaVerification))
            ->action(function () {
                $this->submitVerification('media', $this->partnerMedia, $this->mediaVerification);
            });
    }

    /**
     * Submit journalist verification action
     */
    public function submitJournalistAction(): Action
    {
        return Action::make('submitJournalist')
            ->label(fn () => $this->needsRevision($this->journalistVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi')
            ->icon('heroicon-o-paper-airplane')
            ->color('primary')
            ->requiresConfirmation()
            ->modalHeading('Ajukan Verifikasi Jurnalis')
            ->modalDescription('Apakah Anda yakin ingin mengajukan data jurnalis untuk diverifikasi? Pastikan semua data sudah benar.')
            ->modalSubmitActionLabel('Ya, Ajukan')
            ->visible(fn () => $this->canSubmit($this->journalist, $this->journalistVerification))
            ->action(function () {
                $this->submitVerification('journalist', $this->journalist, $this->journalistVerification);
            });
    }

    /**
     * Handle verification submission
     */
    protected function submitVerification(string $type, $entity, ?VerificationRequest $existingRequest): void
    {
        if (! $entity) {
            Notification::make()
                ->title('Error')
                ->body('Data tidak ditemukan. Silakan lengkapi data terlebih dahulu.')
                ->danger()
                ->send();

            return;
        }

        if ($existingRequest && $existingRequest->status === VerificationStatus::NEED_REVISION) {
            // Resubmit - update existing request
            $existingRequest->update([
                'status' => VerificationStatus::PENDING,
            ]);

            $verification = $existingRequest;
        } else {
            // New submission
            $verification = VerificationRequest::create([
                'verifiable_type' => get_class($entity),
                'verifiable_id' => $entity->id,
                'submitted_by' => auth()->id(),
                'status' => VerificationStatus::PENDING,
            ]);
        }

        // Update the local property
        match ($type) {
            'company' => $this->companyVerification = $verification->fresh(['reviews.reviewer']),
            'media' => $this->mediaVerification = $verification->fresh(['reviews.reviewer']),
            'journalist' => $this->journalistVerification = $verification->fresh(['reviews.reviewer']),
        };

        $entityName = match ($type) {
            'company' => 'Perusahaan',
            'media' => 'Media',
            'journalist' => 'Jurnalis',
        };

        Notification::make()
            ->title('Berhasil!')
            ->body("Data {$entityName} berhasil diajukan untuk diverifikasi.")
            ->success()
            ->send();
    }

    public function getViewData(): array
    {
        return [
            'companyProgress' => $this->companyProgress(),
            'mediaProgress' => $this->mediaProgress(),
            'journalistProgress' => $this->journalistProgress(),
        ];
    }
}
