<?php

namespace App\Filament\Resources;

use App\Enums\AssociationType;
use App\Filament\Exports\AssociationExporter;
use App\Filament\Resources\AssociationResource\Pages;
use App\Filament\Resources\AssociationResource\RelationManagers;
use App\Models\Association;
use BezhanSalleh\FilamentShield\Contracts\HasShieldPermissions;
use Cheesegrits\FilamentGoogleMaps\Fields\Map;
use Filament\Forms;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Forms\Set;
use Filament\Resources\Resource;
use Filament\Tables\Actions\Action;
use Filament\Tables\Actions\ActionGroup;
use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ExportBulkAction;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Support\Facades\Auth;

class AssociationResource extends Resource implements HasShieldPermissions
{
    protected static ?string $model = Association::class;

    protected static ?string $navigationIcon = 'heroicon-o-building-library';

    protected static ?int $navigationSort = 2;

    public static function getModelLabel(): string
    {
        return __('association.association');
    }

    public static function getPluralModelLabel(): string
    {
        return __('association.associations');
    }

    public static function getNavigationGroup(): ?string
    {
        return __('common.navigation.group.association_management');
    }

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                Forms\Components\Section::make(__('association.association_information'))
                    ->description(__('association.association_information_description'))
                    ->schema([
                        SpatieMediaLibraryFileUpload::make('logo')
                            ->label(__('association.logo'))
                            ->collection('logo')
                            ->visibility('private')
                            ->acceptedFileTypes(['image/jpeg', 'image/png'])
                            ->maxSize(2048)
                            ->downloadable()
                            ->required(),

                        TextInput::make('name')
                            ->label(__('association.name'))
                            ->placeholder(__('association.name_placeholder'))
                            ->maxLength(255)
                            ->required(),

                        Forms\Components\Select::make('type')
                            ->label(__('association.type_label'))
                            ->options(AssociationType::getOptions())
                            ->default(AssociationType::ASSOCIATION->value)
                            ->required()
                            ->native(false),

                        TextInput::make('license_number')
                            ->label(__('association.license_number'))
                            ->placeholder(__('association.license_number_placeholder'))
                            ->maxLength(255)
                            ->rules(['regex:/^[1-9][0-9]*$/'])
                            ->validationMessages([
                                'regex' => __('association.license_number_no_leading_zero'),
                            ])
                            ->unique(
                                table: 'associations',
                                column: 'license_number',
                                ignoreRecord: true,
                                modifyRuleUsing: function ($rule, callable $get) {
                                    // Add type to the unique check
                                    return $rule->where('type', $get('type'));
                                }
                            )
                            ->required(),

                        DatePicker::make('license_expiration_date')
                            ->label(__('association.license_expiration_date'))
                            ->required()
                            ->after('today'),

                        TextInput::make('representative_full_name')
                            ->label(__('association.representative'))
                            ->placeholder(__('association.representative_placeholder'))
                            ->required()
                            ->maxLength(255),

                        TextInput::make('representative_position')
                            ->label(__('association.position'))
                            ->placeholder(__('association.position_placeholder'))
                            ->required()
                            ->maxLength(255),
                    ])
                    ->columns(2),

                Forms\Components\Section::make(__('association.contact_information'))
                    ->description(__('association.contact_information_description'))
                    ->schema([
                        TextInput::make('phone_number')
                            ->label(__('association.phone_number'))
                            ->placeholder(__('association.phone_number_placeholder'))
                            ->required()
                            ->maxLength(20),

                        TextInput::make('email')
                            ->label(__('association.email'))
                            ->placeholder(__('association.email_placeholder'))
                            ->email()
                            ->required()
                            ->maxLength(255),
                    ])
                    ->columns(2),

                Forms\Components\Section::make(__('association.national_address'))
                    ->description(__('association.national_address_description'))
                    ->schema([
                        TextInput::make('city')
                            ->label(__('association.city'))
                            ->placeholder(__('association.city_placeholder')),

                        TextInput::make('postal_code')
                            ->label(__('association.postal_code'))
                            ->placeholder(__('association.postal_code_placeholder')),

                        TextInput::make('neighborhood')
                            ->label(__('association.neighborhood'))
                            ->placeholder(__('association.neighborhood_placeholder')),

                        TextInput::make('building_number')
                            ->label(__('association.building_number'))
                            ->placeholder(__('association.building_number_placeholder')),

                        TextInput::make('street')
                            ->label(__('association.street'))
                            ->placeholder(__('association.street_placeholder')),

                        TextInput::make('branch_number')
                            ->label(__('association.branch_number'))
                            ->placeholder(__('association.branch_number_placeholder')),
                    ])
                    ->columns(2),

                Forms\Components\Section::make(__('association.geographic_scope'))
                    ->description(__('association.geographic_scope_description'))
                    ->schema(static::getLocationInformationFields())
                    ->columns(2),

                Forms\Components\Section::make(__('association.banking_details'))
                    ->description(__('association.banking_details_description'))
                    ->schema([
                        TextInput::make('iban')
                            ->label(__('association.iban'))
                            ->placeholder(__('association.iban_placeholder'))
                            ->maxLength(255),

                        TextInput::make('bank_name')
                            ->label(__('association.bank_name'))
                            ->placeholder(__('association.bank_name_placeholder'))
                            ->maxLength(255),

                        TextInput::make('account_holder_name')
                            ->label(__('association.account_holder_name'))
                            ->placeholder(__('association.account_holder_name_placeholder'))
                            ->maxLength(255),
                    ])
                    ->columns(2),

                Forms\Components\Section::make(__('association.documents'))
                    ->description(__('association.documents_description'))
                    ->schema([
                        SpatieMediaLibraryFileUpload::make('authorization_letter')
                            ->label(__('association.authorization_letter_upload'))
                            ->collection('authorization_letter')
                            ->visibility('private')
                            ->acceptedFileTypes(['application/pdf', 'image/jpeg', 'image/png'])
                            ->maxSize(5120)
                            ->downloadable()
                            ->required(),

                        SpatieMediaLibraryFileUpload::make('license_certificate')
                            ->label(__('association.license_upload'))
                            ->collection('license_certificate')
                            ->visibility('private')
                            ->acceptedFileTypes(['application/pdf', 'image/jpeg', 'image/png'])
                            ->maxSize(5120)
                            ->downloadable()
                            ->required(),

                        SpatieMediaLibraryFileUpload::make('iban_certificate')
                            ->label(__('association.iban_certificate'))
                            ->collection('iban_certificate')
                            ->visibility('private')
                            ->acceptedFileTypes(['application/pdf', 'image/jpeg', 'image/png'])
                            ->maxSize(5120)
                            ->downloadable(),

                        SpatieMediaLibraryFileUpload::make('national_address_certificate')
                            ->label(__('association.national_address_certificate'))
                            ->collection('national_address_certificate')
                            ->visibility('private')
                            ->acceptedFileTypes(['application/pdf', 'image/jpeg', 'image/png'])
                            ->maxSize(5120)
                            ->downloadable(),

                        SpatieMediaLibraryFileUpload::make('governance_certificate')
                            ->label(__('association.governance_certificate'))
                            ->collection('governance_certificate')
                            ->visibility('private')
                            ->acceptedFileTypes(['application/pdf', 'image/jpeg', 'image/png'])
                            ->maxSize(5120)
                            ->downloadable(),

                        SpatieMediaLibraryFileUpload::make('financial_reports')
                            ->label(__('association.financial_reports'))
                            ->collection('financial_reports')
                            ->visibility('private')
                            ->acceptedFileTypes(['application/pdf', 'image/jpeg', 'image/png'])
                            ->maxSize(5120)
                            ->downloadable(),

                        SpatieMediaLibraryFileUpload::make('basic_bylaws')
                            ->label(__('association.basic_bylaws'))
                            ->collection('basic_bylaws')
                            ->visibility('private')
                            ->acceptedFileTypes(['application/pdf', 'image/jpeg', 'image/png'])
                            ->maxSize(5120)
                            ->downloadable()
                            ->required(),
                    ])
                    ->columns(2),

                Forms\Components\Section::make(__('association.verification_lock_section'))
                    ->description(__('association.verification_lock_section_description'))
                    ->schema([
                        Forms\Components\Toggle::make('is_verified')
                            ->label(__('association.is_verified'))
                            ->helperText(__('association.is_verified_helper'))
                            ->default(false),

                        Forms\Components\Toggle::make('is_locked')
                            ->label(__('association.is_locked'))
                            ->helperText(__('association.is_locked_helper'))
                            ->default(false),
                    ])
                    ->columns(2),
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('id')
                    ->label(__('common.id'))
                    ->sortable()
                    ->toggleable(),

                TextColumn::make('name')
                    ->label(__('association.name'))
                    ->sortable()
                    ->searchable()
                    ->limit(20)
                    ->tooltip(fn ($record) => $record->name),

                TextColumn::make('type')
                    ->label(__('association.type_label'))
                    ->badge()
                    ->sortable()
                    ->toggleable(),

                TextColumn::make('representative_full_name')
                    ->label(__('association.representative'))
                    ->sortable()
                    ->toggleable()
                    ->limit(20)
                    ->tooltip(fn ($record) => $record->representative_full_name),

                TextColumn::make('license_number')
                    ->label(__('association.license_number'))
                    ->sortable()
                    ->searchable()
                    ->toggleable(),

                TextColumn::make('phone_number')
                    ->label(__('association.phone_number'))
                    ->sortable()
                    ->toggleable(),

                TextColumn::make('is_verified')
                    ->label(__('association.verification_status'))
                    ->badge()
                    ->color(fn (string $state): string => match ($state) {
                        '1' => 'success',
                        '0' => 'danger',
                        default => 'gray',
                    })
                    ->formatStateUsing(fn (string $state): string => $state ? __('association.verified') : __('association.not_verified'))
                    ->sortable()
                    ->toggleable(),

                TextColumn::make('profile_completion_percentage')
                    ->label(__('association.profile_completion'))
                    ->badge()
                    ->color(fn (int $state): string => match (true) {
                        $state >= 90 => 'success',
                        $state >= 70 => 'warning',
                        $state >= 50 => 'info',
                        default => 'danger',
                    })
                    ->formatStateUsing(fn (int $state): string => $state.'%')
                    // ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),

                TextColumn::make('created_at')
                    ->label(__('common.created_at'))
                    ->dateTime()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                SelectFilter::make('is_verified')
                    ->label(__('association.verification_status'))
                    ->options([
                        1 => __('association.verified'),
                        0 => __('association.not_verified'),
                    ]),

                SelectFilter::make('is_locked')
                    ->label(__('association.lock_status'))
                    ->options([
                        1 => __('association.locked'),
                        0 => __('association.unlocked'),
                    ]),
            ])
            ->headerActions([
                ExportAction::make()
                    ->exporter(AssociationExporter::class),
            ])
            ->actions([
                ActionGroup::make([
                    ViewAction::make(),
                    EditAction::make(),

                    Action::make('verify')
                        ->label(__('association.action_verify'))
                        ->icon('heroicon-o-shield-check')
                        ->visible(fn ($record) => ! $record->is_verified && Auth::user()->can('verify_association'))
                        ->color('success')
                        ->requiresConfirmation()
                        ->modalHeading(__('association.confirm_verify_title'))
                        ->modalDescription(__('association.confirm_verify_description'))
                        ->action(fn ($record) => $record->update(['is_verified' => true])),

                    Action::make('unverify')
                        ->label(__('association.action_unverify'))
                        ->icon('heroicon-o-shield-exclamation')
                        ->visible(fn ($record) => $record->is_verified && Auth::user()->can('unverify_association'))
                        ->color('warning')
                        ->requiresConfirmation()
                        ->modalHeading(__('association.confirm_unverify_title'))
                        ->modalDescription(__('association.confirm_unverify_description'))
                        ->action(fn ($record) => $record->update(['is_verified' => false])),

                    Action::make('lock')
                        ->label(__('association.action_lock'))
                        ->icon('heroicon-o-lock-closed')
                        ->visible(fn ($record) => ! $record->is_locked && Auth::user()->can('lock_profile_association'))
                        ->color('danger')
                        ->requiresConfirmation()
                        ->modalHeading(__('association.confirm_lock_title'))
                        ->modalDescription(__('association.confirm_lock_description'))
                        ->action(fn ($record) => $record->update(['is_locked' => true])),

                    Action::make('unlock')
                        ->label(__('association.action_unlock'))
                        ->icon('heroicon-o-lock-open')
                        ->visible(fn ($record) => $record->is_locked && Auth::user()->can('unlock_profile_association'))
                        ->color('success')
                        ->requiresConfirmation()
                        ->modalHeading(__('association.confirm_unlock_title'))
                        ->modalDescription(__('association.confirm_unlock_description'))
                        ->action(fn ($record) => $record->update(['is_locked' => false])),

                    DeleteAction::make(),
                ]),
            ])
            ->bulkActions([
                BulkActionGroup::make([
                    ExportBulkAction::make()
                        ->exporter(AssociationExporter::class),
                    DeleteBulkAction::make(),
                ]),
            ])
            ->defaultSort('created_at', 'desc');
    }

    public static function getEloquentQuery(): \Illuminate\Database\Eloquent\Builder
    {
        return parent::getEloquentQuery()
            ->with([
                'states',
                'cities',
                'centers',
                'residentialGatherings',
            ]);
    }

    public static function getRelations(): array
    {
        return [
            RelationManagers\OrdersRelationManager::class,
            RelationManagers\ProjectChartersRelationManager::class,
            RelationManagers\WellLicensesRelationManager::class,
            RelationManagers\StationLicensesRelationManager::class,
        ];
    }

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListAssociations::route('/'),
            'create' => Pages\CreateAssociation::route('/create'),
            'view' => Pages\ViewAssociation::route('/{record}'),
            'edit' => Pages\EditAssociation::route('/{record}/edit'),
        ];
    }

    public static function getPermissionPrefixes(): array
    {
        return [
            'view',
            'view_any',
            'create',
            'update',
            'restore',
            'restore_any',
            'replicate',
            'reorder',
            'delete',
            'delete_any',
            'force_delete',
            'force_delete_any',

            // Association specific permissions
            'verify',
            'unverify',
            'lock_profile',
            'unlock_profile', // this will enable editing of the association profile
        ];
    }

    /**
     * Get the location information form fields
     */
    public static function getLocationInformationFields(): array
    {
        return [
            Forms\Components\Select::make('states')
                ->label(__('association.states'))
                ->relationship('states', 'name')
                ->multiple()
                ->searchable()
                ->preload()
                ->live()
                ->afterStateUpdated(function (Set $set) {
                    $set('cities', []);
                    $set('centers', []);
                })
                ->options(function (Get $get) {
                    return \App\Models\State::pluck('name', 'id');
                }),

            Forms\Components\Select::make('cities')
                ->label(__('association.cities'))
                ->relationship('cities', 'name')
                ->multiple()
                ->searchable()
                ->preload()
                ->live()
                ->afterStateUpdated(function (Set $set) {
                    $set('centers', []);
                })
                ->options(function (Get $get) {
                    $stateIds = $get('states');
                    if (! $stateIds || empty($stateIds)) {
                        return [];
                    }

                    return \App\Models\City::whereIn('state_id', $stateIds)
                        ->pluck('name', 'id');
                }),

            Forms\Components\Select::make('centers')
                ->label(__('association.centers'))
                ->relationship('centers', 'name')
                ->multiple()
                ->searchable()
                ->getSearchResultsUsing(
                    fn (string $search, Get $get): array => \App\Models\Center::whereIn('city_id', $get('cities'))
                        ->where('name', 'like', "%{$search}%")
                        ->pluck('name', 'id')
                        ->toArray()
                )
                ->preload()
                ->live()
                ->options(function (Get $get) {
                    $cityIds = $get('cities');
                    if (! $cityIds || empty($cityIds)) {
                        return [];
                    }

                    return \App\Models\Center::whereIn('city_id', $cityIds)->pluck('name', 'id');
                })
                ->afterStateUpdated(function (Set $set, $state, Get $get) {
                    $set('residentialGatherings', []);
                }),

            Forms\Components\Select::make('residentialGatherings')
                ->label(__('order.residential_gatherings'))
                ->helperText(__('order.residential_gatherings_helper'))
                ->relationship('residentialGatherings', 'name')
                ->multiple()
                ->searchable()
                ->getSearchResultsUsing(function (string $search, Get $get): array {
                    $centerIds = $get('centers');
                    if (empty($centerIds)) {
                        return [];
                    }

                    return \App\Models\ResidentialGathering::whereIn('center_id', $centerIds)
                        ->where('name', 'like', "%{$search}%")
                        ->with('center')
                        ->get()
                        ->mapWithKeys(function ($rg) {
                            return [$rg->id => $rg->name.' ('.$rg->center->name.')'];
                        })
                        ->toArray();
                })
                ->getOptionLabelFromRecordUsing(fn ($record) => $record->name.' ('.$record->center->name.')')
                ->preload()
                ->options(function (Get $get) {
                    $centerIds = $get('centers');
                    if (empty($centerIds)) {
                        return [];
                    }

                    return \App\Models\ResidentialGathering::whereIn('center_id', $centerIds)
                        ->with('center')
                        ->get()
                        ->mapWithKeys(function ($rg) {
                            return [$rg->id => $rg->name.' ('.$rg->center->name.')'];
                        })
                        ->toArray();
                }),

            Map::make('location')
                ->label(__('association.location'))
                ->mapControls([
                    'mapTypeControl' => true,
                    'scaleControl' => true,
                    'streetViewControl' => true,
                    'rotateControl' => true,
                    'fullscreenControl' => true,
                    'searchBoxControl' => false,
                    'zoomControl' => true,
                ])
                ->height(fn () => '400px')
                ->defaultZoom(8)
                // default location to riyadh
                ->defaultLocation([24.7136, 46.6753])
                ->autocomplete('address')
                ->clickable(true)
                ->reactive()
                ->afterStateUpdated(function (Set $set, $state) {
                    if (is_array($state)) {
                        $set('lat', $state['lat']);
                        $set('lng', $state['lng']);
                    }
                })
                ->afterStateHydrated(function (Set $set, $state, $record) {
                    if ($record && $record->lat && $record->lng) {
                        $set('location', [
                            'lat' => (float) $record->lat,
                            'lng' => (float) $record->lng,
                        ]);
                    }
                }),

            Forms\Components\Hidden::make('lat'),
            Forms\Components\Hidden::make('lng'),
        ];
    }
}
