<?php

namespace App\Filament\Resources\Manage\Cooperations\RelationManagers;

use App\Enums\ApprovalStatus;
use App\Enums\CooperationStatus;
use App\Enums\RoleEnum;
use App\Filament\Resources\Manage\Cooperations\Actions\Report\AcceptAction;
use App\Filament\Resources\Manage\Cooperations\Actions\Report\RejectAction;
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
use App\Filament\Support\CheerfulNotification;
use App\Models\Report;
use App\Models\User;
use App\Notifications\BroadcastNotification;
use Filament\Actions\Action;
use Filament\Actions\CreateAction;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
use Filament\Support\Enums\Width;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;

class ReportRelationManager extends RelationManager
{
    protected static string $relationship = 'reports';

    protected static ?string $title = 'Laporan';

    public function isReadOnly(): bool
    {
        return false;
    }

    public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool
    {
        if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
            return $ownerRecord->cooperationMedia()
                ->whereHas('partnerMedia', function ($query) {
                    $query->whereHas('company', function ($query) {
                        $query->where('user_id', auth()->id());
                    });
                })
                ->where('status', ApprovalStatus::ACCEPTED)
                ->exists();
        }

        return true;
    }

    public static function getBadge(Model $ownerRecord, string $pageClass): ?string
    {
        if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
            return $ownerRecord->reports()
                ->whereHas('mediaTaskAssignment.partnerMedia.company', function ($q) {
                    $q->where('user_id', auth()->id());
                })
                ->count();
        }

        return $ownerRecord->reports()->count();
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                TextInput::make('title')
                    ->placeholder('Dirgahayu Purwakarta')
                    ->required()
                    ->autocomplete(false)
                    ->autofocus(),

                DatePicker::make('publication_date')
                    ->label('Tanggal Publikasi')
                    ->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
                    ->native(false)
                    ->displayFormat('l, d F Y')
                    ->required(),

                TextInput::make('link')
                    ->label('Tautan')
                    ->placeholder('https://example.com')
                    ->maxLength(255)
                    ->url()
                    ->required()
                    ->autocomplete(false),

                Textarea::make('description')
                    ->label('Deskripsi')
                    ->placeholder('....')
                    ->required()
                    ->autocomplete(false),

                SpatieMediaLibraryFileUpload::make('image')
                    ->label('Gambar')
                    ->disk(config('filesystems.default'))
                    ->acceptedFileTypes(['image/*'])
                    ->maxSize(1024 * 3)
                    ->collection('reports')
                    ->image()
                    ->required(),
            ])
            ->columns(1);
    }

    public function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('mediaTaskAssignment.partnerMedia.name')
                    ->label('Media')
                    ->searchable()
                    ->visible(! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),

                TextColumn::make('title')
                    ->label('Judul')
                    ->searchable(),

                TextColumn::make('publication_date')
                    ->label('Tanggal Publikasi')
                    ->date('l, d F Y'),

                TextColumn::make('link')
                    ->label('Link')
                    ->limit(30)
                    ->url(fn (Report $record): string => $record->link)
                    ->openUrlInNewTab(),

                TextColumn::make('status')
                    ->label('Status')
                    ->badge(),

                TextColumn::make('rejectionReasons.reason')
                    ->label('Alasan Penolakan')
                    ->searchable(),
            ])
            ->filters([])
            ->recordActions([
                AcceptAction::make('accept'),

                RejectAction::make('reject'),
            ])
            ->headerActions([
                CreateAction::make()
                    ->label('Buat Laporan')
                    ->modalWidth(Width::Large)
                    ->modalHeading('Buat Laporan')
                    ->mutateDataUsing(function (array $data): array {
                        $taskAssignment = $this->getOwnerRecord()->taskAssignment;

                        if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
                            $mediaTaskAssignment = $taskAssignment?->mediaTaskAssignments()
                                ->whereHas('partnerMedia.company', function ($query) {
                                    $query->where('user_id', auth()->id());
                                })
                                ->first();

                            $data['media_task_assignment_id'] = $mediaTaskAssignment?->id;
                        }

                        return $data;
                    })
                    ->successNotification(null)
                    ->after(function (Report $record): void {
                        CheerfulNotification::success(
                            'Laporan Berhasil Terkirim! 🚀✨',
                            'Hore! Laporan Anda sudah masuk ke sistem. Admin akan segera memeriksanya. Terima kasih atas kerja kerasnya! 💪'
                        )->send();

                        // Notify Admins
                        User::superAdmin()
                            ->get()
                            ->each(function ($admin) use ($record): void {
                                $user = auth()->user();

                                $admin->notify(new BroadcastNotification([
                                    'title' => 'Ada Laporan Baru! 📝✨',
                                    'body' => "Halo Admin! {$user->name} baru saja mengirimkan laporan \"{$record->title}\" untuk kerja sama \"{$this->getOwnerRecord()->title}\". Yuk, dicek! 😊",
                                    'action' => [
                                        Action::make('view')
                                            ->label('Lihat')
                                            ->url(CooperationResource::getUrl('view', ['record' => $this->getOwnerRecord()->id, 'relation' => 3])),
                                    ],
                                ]));
                            });
                    })
                    ->visible(function (): bool {
                        $user = auth()->user();

                        if (! $user || ! $user->hasRole(RoleEnum::PERUSAHAAN->value)) {
                            return false;
                        }

                        $taskAssignment = $this->getOwnerRecord()->taskAssignment;

                        if (! $taskAssignment) {
                            return false;
                        }

                        return $this->getOwnerRecord()->status === CooperationStatus::ASSIGNMENT
                            && $taskAssignment->start_date->toDateString() <= now()->toDateString()
                            && $taskAssignment->end_date->toDateString() >= now()->toDateString()
                            && $taskAssignment->reports()
                                ->whereHas('mediaTaskAssignment.partnerMedia.company', fn ($q) => $q->where('user_id', auth()->id()))
                                ->where('reports.status', '!=', ApprovalStatus::REJECTED)
                                ->count() < $taskAssignment->report_amount;
                    }),
            ])
            ->toolbarActions([])
            ->emptyStateIcon(Heroicon::InboxArrowDown)
            ->emptyStateDescription('Tidak ada laporan yang diajukan.')
            ->defaultSort('created_at', 'desc')
            ->modifyQueryUsing(function ($query) {
                $user = auth()->user();

                if (! $user->hasRole(RoleEnum::PERUSAHAAN->value)) {
                    return $query;
                }

                $query->whereHas('mediaTaskAssignment.partnerMedia.company', function ($q) use ($user) {
                    $q->where('user_id', $user->id);
                });
            });
    }
}
