<?php

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

use App\Enums\ApprovalStatus;
use App\Enums\CooperationStatus;
use App\Enums\RoleEnum;
use App\Filament\Actions\Cheerful\DeleteAction;
use App\Filament\Actions\Cheerful\EditAction;
use App\Filament\Actions\DefaultBulkActions;
use App\Filament\Columns\TimestampColumns;
use App\Filament\Exports\CooperationExcelExport;
use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\AcceptAction;
use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\CompleteCooperationAction;
use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\CreateTaskAssignmentAction;
use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\ProceedToPaymentAction;
use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\RejectAction;
use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\SendProposalAction;
use App\Models\Cooperation;
use Carbon\CarbonInterface;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Enums\FiltersLayout;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use pxlrbt\FilamentExcel\Actions\Tables\ExportAction;

class CooperationsTable
{
    public static function configure(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('title')
                    ->label('Judul')
                    ->searchable()
                    ->sortable()
                    ->wrap(),

                TextColumn::make('partnerMedia.name')
                    ->label('Media')
                    ->listWithLineBreaks()
                    ->limitList(3)
                    ->expandableLimitedList()
                    ->badge()
                    ->visible(! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),

                TextColumn::make('initial_submission_date')
                    ->label('Tgl Pengajuan Awal')
                    ->searchable()
                    ->sortable()
                    ->date('l, d F Y'),

                TextColumn::make('final_submission_date')
                    ->label('Tgl Pengajuan Akhir')
                    ->searchable()
                    ->sortable()
                    ->date('l, d F Y')
                    ->description(
                        fn (Cooperation $record): string => now()->greaterThan($record->final_submission_date->copy()->endOfDay())
                            ? 'Waktu Pengajuan Habis'
                            : 'Sisa waktu pengajuan: '.now()->diffForHumans(
                                $record->final_submission_date->copy()->endOfDay(),
                                ['syntax' => CarbonInterface::DIFF_ABSOLUTE]
                            )
                    ),

                TextColumn::make('status')
                    ->searchable()
                    ->sortable()
                    ->badge(),

                TextColumn::make('media_count')
                    ->label('Tanggapan Media')
                    ->html()
                    ->getStateUsing(function (Cooperation $record): string {
                        $record->loadCount([
                            'partnerMedia as approved_count' => fn (Builder $query): Builder => $query->wherePivotAccepted(),
                            'partnerMedia as rejected_count' => fn (Builder $query): Builder => $query->wherePivotRejected(),
                            'partnerMedia as pending_count' => fn (Builder $query): Builder => $query->wherePivotPending(),
                        ]);

                        $totalCount = $record->partnerMedia()->count();

                        return "Menerima: {$record->approved_count}<br>
                            Menolak: {$record->rejected_count}<br>
                            Belum Menanggapi: {$record->pending_count}<br>
                            Total: {$totalCount}";
                    })
                    ->visible(! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),

                TextColumn::make('status_tanggapan')
                    ->label('Tanggapan')
                    ->getStateUsing(function (Cooperation $record): ?ApprovalStatus {
                        if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
                            $cooperationMedia = $record->cooperationMedia()
                                ->whereHas('partnerMedia', function (Builder $query): void {
                                    $query->whereHas('company', function (Builder $subQuery): void {
                                        $subQuery->where('user_id', auth()->id());
                                    });
                                })
                                ->first();

                            return $cooperationMedia?->status;
                        }

                        return null;
                    })
                    ->badge()
                    ->visible(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),

                TextColumn::make('payment_amount')
                    ->label('Jumlah Pembayaran')
                    ->money('IDR')
                    ->sortable()
                    ->placeholder('Belum ditentukan')
                    ->toggleable(isToggledHiddenByDefault: true),

                TextColumn::make('payment_date')
                    ->label('Tanggal Pembayaran')
                    ->date('l, d F Y')
                    ->sortable()
                    ->placeholder('Belum dibayar')
                    ->toggleable(isToggledHiddenByDefault: true),

                TextColumn::make('completed_at')
                    ->label('Tanggal Selesai')
                    ->date('l, d F Y')
                    ->sortable()
                    ->placeholder('Masih berjalan')
                    ->toggleable(isToggledHiddenByDefault: true),

                TextColumn::make('description')
                    ->label('Deskripsi')
                    ->searchable()
                    ->limit(50)
                    ->wrap()
                    ->toggleable(isToggledHiddenByDefault: true),

                ...TimestampColumns::make(),
            ])
            ->filters(
                auth()->user()->hasRole(RoleEnum::DEVELOPER->value) || auth()->user()->hasRole(RoleEnum::ADMINISTRATOR->value)
                    ? [
                        TrashedFilter::make()
                            ->native(false)
                            ->visible(fn (): bool => auth()->user()?->hasRole(RoleEnum::DEVELOPER->value)),

                        SelectFilter::make('status')
                            ->label('Status')
                            ->options(CooperationStatus::class)
                            ->native(false),

                        SelectFilter::make('partnerMedia')
                            ->label('Media')
                            ->relationship('partnerMedia', 'name')
                            ->searchable()
                            ->preload(),

                        Filter::make('title')
                            ->schema([
                                TextInput::make('title')
                                    ->label('Nama Kegiatan')
                                    ->placeholder('Cari nama kegiatan...'),
                            ])
                            ->query(function (Builder $query, array $data): Builder {
                                return $query->when(
                                    $data['title'],
                                    fn (Builder $query, $title): Builder => $query->where('title', 'like', "%{$title}%"),
                                );
                            }),

                        Filter::make('date_filter')
                            ->schema([
                                Select::make('date_type')
                                    ->label('Jenis Filter Tanggal')
                                    ->options([
                                        'date' => 'Tanggal Penyerahan Awal',
                                        'month' => 'Bulan & Tahun',
                                        'year' => 'Tahun',
                                        'range' => 'Rentang Tanggal',
                                    ])
                                    ->live()
                                    ->native(false),

                                DatePicker::make('specific_date')
                                    ->label('Tanggal')
                                    ->visible(fn (Get $get) => $get('date_type') === 'date')
                                    ->native(false)
                                    ->displayFormat('l, d F Y'),

                                Select::make('month')
                                    ->label('Bulan')
                                    ->options([
                                        1 => 'Januari',
                                        2 => 'Februari',
                                        3 => 'Maret',
                                        4 => 'April',
                                        5 => 'Mei',
                                        6 => 'Juni',
                                        7 => 'Juli',
                                        8 => 'Agustus',
                                        9 => 'September',
                                        10 => 'Oktober',
                                        11 => 'November',
                                        12 => 'Desember',
                                    ])
                                    ->visible(fn (Get $get) => $get('date_type') === 'month')
                                    ->native(false),

                                Select::make('year')
                                    ->label('Tahun')
                                    ->options(function () {
                                        $years = range(date('Y'), 2020);

                                        return array_combine($years, $years);
                                    })
                                    ->visible(fn (Get $get) => in_array($get('date_type'), ['month', 'year']))
                                    ->native(false),

                                DatePicker::make('start_date')
                                    ->label('Mulai Tanggal')
                                    ->visible(fn (Get $get) => $get('date_type') === 'range')
                                    ->native(false)
                                    ->displayFormat('l, d F Y'),

                                DatePicker::make('end_date')
                                    ->label('Sampai Tanggal')
                                    ->visible(fn (Get $get) => $get('date_type') === 'range')
                                    ->native(false)
                                    ->displayFormat('l, d F Y'),
                            ])
                            ->query(function (Builder $query, array $data): Builder {
                                $type = $data['date_type'] ?? null;
                                $column = 'initial_submission_date';

                                if ($type === 'date' && ! empty($data['specific_date'])) {
                                    return $query->whereDate($column, $data['specific_date']);
                                }
                                if ($type === 'month' && ! empty($data['month']) && ! empty($data['year'])) {
                                    return $query->whereMonth($column, $data['month'])
                                        ->whereYear($column, $data['year']);
                                }
                                if ($type === 'year' && ! empty($data['year'])) {
                                    return $query->whereYear($column, $data['year']);
                                }
                                if ($type === 'range' && ! empty($data['start_date']) && ! empty($data['end_date'])) {
                                    return $query->whereBetween($column, [$data['start_date'], $data['end_date']]);
                                }

                                return $query;
                            }),
                    ] : [],
                FiltersLayout::AboveContentCollapsible
            )
            ->filtersFormColumns(3)
            ->recordActions([
                ViewAction::make(),

                AcceptAction::make('accept'),

                RejectAction::make('reject'),

                SendProposalAction::make('sendProposal'),

                CreateTaskAssignmentAction::make('createTaskAssignment'),

                ProceedToPaymentAction::make('proceedToPayment'),

                CompleteCooperationAction::make('completeCooperation'),

                EditAction::make(),

                DeleteAction::make(),
            ])
            ->headerActions([
                ExportAction::make()
                    ->exports([
                        CooperationExcelExport::make(),
                    ])
                    ->color('success')
                    ->visible(fn (): bool => auth()->user()->hasRole(RoleEnum::DEVELOPER->value) || auth()->user()->hasRole(RoleEnum::ADMINISTRATOR->value)),

            ])
            ->toolbarActions([
                BulkActionGroup::make([
                    ...DefaultBulkActions::make('Kerja Sama'),
                ]),
            ])
            ->emptyStateIcon(Heroicon::HandRaised)
            ->emptyStateDescription('Setelah Anda membuat data pertama, maka akan muncul disini.')
            ->defaultSort('created_at', 'desc')
            ->deferFilters(false);
    }
}
