<?php

namespace App\Filament\Pages\Media;

use App\Enums\RoleEnum;
use App\Enums\VerificationStatus;
use App\Filament\Pages\Media\Concerns\HasMediaActions;
use App\Filament\Pages\Media\Schemas\MediaForm;
use App\Filament\Pages\Media\Services\MediaSaveService;
use App\Filament\Support\CheerfulNotification;
use App\Models\Company;
use App\Models\PartnerMedia;
use App\Models\VerificationRequest;
use BackedEnum;
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Pages\Page;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Illuminate\Validation\ValidationException;
use UnitEnum;

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

    public ?Company $company = null;

    public array $data = [];

    public array $originalDocuments = [];

    public ?PartnerMedia $media = null;

    protected static ?string $model = PartnerMedia::class;

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

    protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedNewspaper;

    protected static ?string $navigationLabel = 'Media';

    protected static ?int $navigationSort = 3;

    public bool $restricted = false;

    public bool $isVerificationStage = false;

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

    protected static ?string $title = 'Media';

    public ?VerificationRequest $verificationRequest = null;

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

    public static function canAccess(): bool
    {
        return auth()->user()->can('View:Media');
    }

    public function mount(): void
    {
        if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value) && ! auth()->user()->company) {
            $this->restricted = true;

            return;
        }

        $company = auth()->user()->company;

        if (! $company) {
            $this->restricted = true;

            return;
        }

        $this->company = $company;

        $this->isVerificationStage = in_array($company?->verificationRequest?->status, [
            VerificationStatus::PENDING,
            VerificationStatus::REJECTED,
        ]) || $company->verificationRequest()->pending()->exists();

        $verificationRequest = $this->company->verificationRequest()
            ->latest()
            ->first();

        $this->verificationRequest = $verificationRequest;

        $media = $company->partnerMedia;

        if (! $media) {
            return;
        }

        $this->media = $media;

        $this->form->fill($media->toArray());

        $documents = [
            'journalism_organization',
            'press_council_certificate',
        ];

        $mediaItems = $media->getMedia('partnerMedia');

        foreach ($documents as $docType) {
            $mediaItem = $mediaItems
                ->where('custom_properties.doc_type', str($docType)->replace('_docs', '')->slug('-'))
                ->sortByDesc('created_at')
                ->first();

            if ($mediaItem) {
                $path = $mediaItem->getPathRelativeToRoot();
                $this->data["{$docType}_docs"] = [$path];
                $this->originalDocuments["{$docType}_docs"] = [$path];
            }
        }
    }

    public static function form(Schema $schema): Schema
    {
        return MediaForm::configure($schema);
    }

    public function save(): void
    {
        $this->mountAction('save');
    }

    public function needsMediaReview(): bool
    {
        return $this->media?->company?->verificationRequest?->status !== null;
    }

    public function handleMediaSave(array $data = []): void
    {
        try {
            $media = MediaSaveService::handle(
                existingMedia: $this->media,
                companyId: $this->company->id,
                formState: $this->form->getState(),
                pageData: $this->data,
                originalDocuments: $this->originalDocuments,
                needsReview: $this->needsMediaReview(),
                actionData: $data,
            );

            if ($this->needsMediaReview()) {
                return;
            }

            $this->media = $media;

            CheerfulNotification::create()->send();
        } catch (ValidationException $e) {
            $this->unmountAction();

            throw $e;
        }
    }
}
