<?php

namespace App\Filament\Pages;

use App\Enums\DecisionAdmin;
use App\Enums\VerificationStatus;
use App\Filament\Resources\Manage\Partners\Pages\ViewPartner;
use App\Filament\Support\CheerfulNotification;
use App\Models\User;
use App\Models\VerificationRequest;
use App\Models\VerificationReview;
use App\Notifications\BroadcastNotification;
use BackedEnum;
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Pages\Page;
use Filament\Support\Enums\Width;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use UnitEnum;

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

    public string $filterStatus = 'all';

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

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-user-group';

    protected static ?string $navigationLabel = 'Verifikasi Rekanan';

    protected static ?int $navigationSort = 6;

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

    protected static ?string $title = 'Verifikasi Rekanan';

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

    public static function getNavigationBadge(): ?string
    {
        return VerificationRequest::query()->pending()->count();
    }

    public function getVerifications(): LengthAwarePaginator
    {
        $query = VerificationRequest::with([
            'company.user',
            'company.partnerMedia',
            'company.partnerMedia.journalists',
            'submittedBy',
            'reviews.reviewer',
        ])
            ->latest('updated_at');

        // Apply status filter
        if ($this->filterStatus !== 'all') {
            $query->where('status', $this->filterStatus);
        }

        return $query->paginate(12);
    }

    public function setFilter(string $status): void
    {
        $this->filterStatus = $status;
    }

    public function getStatusCounts(): array
    {
        return [
            'all' => VerificationRequest::count(),
            'pending' => VerificationRequest::pending()->count(),
            'revision' => VerificationRequest::needRevision()->count(),
            'approved' => VerificationRequest::approved()->count(),
            'rejected' => VerificationRequest::rejected()->count(),
        ];
    }

    /**
     * Get company name from verification request
     */
    public function getCompanyName(VerificationRequest $request): string
    {
        return $request->company?->name ?? 'Data tidak ditemukan';
    }

    /**
     * Get detail URL for the company
     */
    public function getDetailUrl(VerificationRequest $request): ?string
    {
        if (! $request->company || ! $request->company->user_id) {
            return null;
        }

        return ViewPartner::getUrl(['record' => $request->company->user_id]);
    }

    /**
     * Get verification summary data
     */
    public function getVerificationSummary(VerificationRequest $request): array
    {
        $company = $request->company;
        $media = $company?->partnerMedia;
        $journalists = $media?->journalists ?? collect();

        return [
            'company' => [
                'name' => $company?->name ?? 'Belum diisi',
                'email' => $company?->email ?? '-',
                'exists' => $company !== null,
            ],
            'media' => [
                'name' => $media?->name ?? 'Belum diisi',
                'type' => $media?->type?->getLabel() ?? '-',
                'exists' => $media !== null,
            ],
            'journalists' => [
                'count' => $journalists->count(),
                'names' => $journalists->pluck('name')->take(3)->toArray(),
                'exists' => $journalists->count() > 0,
            ],
        ];
    }

    /**
     * Get card data for verification request
     */
    public function getCardData(VerificationRequest $verification): array
    {
        $latestReview = $verification->reviews->first();
        $summary = $this->getVerificationSummary($verification);
        $status = $verification->status;

        return [
            'companyName' => $this->getCompanyName($verification),
            'detailUrl' => $this->getDetailUrl($verification),
            'status' => $status,
            'statusLabel' => $status->getLabel(),
            'statusColor' => $status->getColor(),
            'summary' => $summary,
            'latestReview' => $latestReview,
            'latestReviewNote' => $latestReview?->note,
            'latestReviewDecision' => $latestReview?->decision,
            'latestReviewDecisionLabel' => $latestReview?->decision?->getLabel(),
            'latestReviewDecisionColor' => $latestReview?->decision?->getColor(),
            'latestReviewReviewer' => $latestReview?->reviewer?->name ?? 'Admin',
            'latestReviewCreatedAt' => $latestReview?->created_at,
            'submittedBy' => $verification->submittedBy?->name ?? 'Unknown',
            'reviewsCount' => $verification->reviews->count(),
            'canApprove' => $status === VerificationStatus::PENDING,
            'isPending' => $status === VerificationStatus::PENDING,
            'isRevision' => $status === VerificationStatus::NEED_REVISION,
            'isApproved' => $status === VerificationStatus::APPROVED,
            'isRejected' => $status === VerificationStatus::REJECTED,
        ];
    }

    /**
     * Approve verification action
     */
    public function approveAction(): Action
    {
        return Action::make('approve')
            ->label('Setujui')
            ->color('success')
            ->icon('heroicon-o-check')
            ->size('sm')
            ->requiresConfirmation()
            ->modalHeading('Setujui Verifikasi')
            ->modalDescription('Apakah Anda yakin ingin menyetujui verifikasi ini? Pastikan data sudah benar dan lengkap.')
            ->modalSubmitActionLabel('Ya, Setujui')
            ->action(function (array $arguments, array $data): void {
                $this->processReview($arguments['id'], DecisionAdmin::APPROVED, $data['note'] ?? null);
            });
    }

    /**
     * Revision verification action
     */
    public function revisionAction(): Action
    {
        return Action::make('revision')
            ->label('Minta Revisi')
            ->color('warning')
            ->icon('heroicon-o-pencil-square')
            ->size('sm')
            ->modalHeading('Minta Revisi')
            ->modalDescription('Pengguna akan diminta untuk memperbaiki data sesuai catatan yang diberikan.')
            ->schema([
                Textarea::make('note')
                    ->label('Catatan Revisi')
                    ->required()
                    ->placeholder('Jelaskan bagian yang perlu diperbaiki...')
                    ->autocomplete(false)
                    ->autofocus(),
            ])
            ->action(function (array $arguments, array $data): void {
                $this->processReview($arguments['id'], DecisionAdmin::NEED_REVISION, $data['note']);
            })
            ->modalWidth(Width::Large);
    }

    /**
     * Reject verification action
     */
    public function rejectAction(): Action
    {
        return Action::make('reject')
            ->label('Tolak')
            ->color('danger')
            ->icon('heroicon-o-x-mark')
            ->size('sm')
            ->requiresConfirmation()
            ->modalHeading('Tolak Verifikasi')
            ->modalDescription('Pengajuan akan ditolak secara permanen. Pengguna tidak dapat mengajukan ulang untuk data ini.')
            ->modalSubmitActionLabel('Ya, Tolak')
            ->schema([
                Textarea::make('note')
                    ->label('Alasan Penolakan')
                    ->required()
                    ->placeholder('Jelaskan alasan pengajuan ditolak...')
                    ->autocomplete(false)
                    ->autofocus(),
            ])
            ->action(function (array $arguments, array $data): void {
                $this->processReview($arguments['id'], DecisionAdmin::REJECTED, $data['note']);
            });
    }

    /**
     * Process review decision
     */
    protected function processReview(int $requestId, DecisionAdmin $decision, ?string $note): void
    {
        $verificationRequest = VerificationRequest::with(['company.partnerMedia.journalists'])->find($requestId);

        if (! $verificationRequest) {
            CheerfulNotification::danger(
                'Belum ketemu nih 🙌',
                'Data verifikasi belum kami temukan. Coba sebentar lagi, ya.',
            )
                ->send();

            return;
        }

        try {
            DB::beginTransaction();

            // Create review record
            VerificationReview::create([
                'verification_request_id' => $verificationRequest->id,
                'reviewer_id' => auth()->id(),
                'decision' => $decision,
                'note' => $note,
            ]);

            // Update verification request status
            $newStatus = match ($decision) {
                DecisionAdmin::APPROVED => VerificationStatus::APPROVED,
                DecisionAdmin::NEED_REVISION => VerificationStatus::NEED_REVISION,
                DecisionAdmin::REJECTED => VerificationStatus::REJECTED,
            };

            $verificationRequest->update([
                'status' => $newStatus,
            ]);

            DB::commit();

            $actionLabel = match ($decision) {
                DecisionAdmin::APPROVED => 'disetujui',
                DecisionAdmin::NEED_REVISION => 'diminta revisi',
                DecisionAdmin::REJECTED => 'ditolak',
            };

            CheerfulNotification::success(
                'Berhasil Diproses! ✨',
                "Mantap! Verifikasi telah {$actionLabel} dan notifikasi sudah dikirim ke pengguna. Kerja bagus, Admin! 💪"
            )
                ->send();

            // Notify User
            $partnerUser = $verificationRequest->company?->user;
            if ($partnerUser) {
                $statusTitle = match ($decision) {
                    DecisionAdmin::APPROVED => 'Horee! Verifikasi Disetujui 🎉',
                    DecisionAdmin::NEED_REVISION => 'Yah, Ada Yang Perlu Direvisi nih 📝',
                    DecisionAdmin::REJECTED => 'Maaf, Verifikasi Ditolak 😔',
                };

                $body = match ($decision) {
                    DecisionAdmin::APPROVED => 'Yeay! Pengajuan verifikasi perusahaan Anda telah disetujui. Sekarang Anda sudah resmi terverifikasi dan bekerja sama dengan kami! 🎊',
                    DecisionAdmin::NEED_REVISION => 'Ayo sedikit lagi! Admin meminta beberapa perbaikan pada pengajuan Anda agar bisa segera disetujui. 💪',
                    DecisionAdmin::REJECTED => 'Yah, maaf banget... pengajuan verifikasi perusahaan Anda belum bisa kami terima saat ini. 💔',
                };

                if ($note) {
                    $body .= "\n\nCatatan Admin: {$note}";
                }

                $partnerUser->notify(new BroadcastNotification([
                    'title' => $statusTitle,
                    'body' => $body,
                    'action' => [
                        Action::make('view')
                            ->label('Lihat')
                            ->url(Verification::getUrl()),
                    ],
                ]));
            }
        } catch (\Throwable $e) {
            DB::rollBack();
            Log::error('Verification processing failed', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'request_id' => $requestId,
                'decision' => $decision->value,
            ]);

            CheerfulNotification::danger(
                'Terjadi Kesalahan ⚠️',
                'Proses verifikasi gagal karena kesalahan sistem. Tim kami sudah mencatat masalah ini. Silakan coba lagi nanti.',
            )
                ->send();
        }
    }
}
