<?php

namespace App\Filament\Association\Pages;

use App\Models\Election;
use App\Models\ElectionSetting;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Actions\Action;
use Filament\Facades\Filament;

class ElectionSettings extends Page
{
    protected static ?string $navigationIcon = 'heroicon-o-cog-6-tooth';
    protected static string $view = 'filament.association.pages.election-settings';
    protected static ?string $navigationGroup = 'Elections & Voting';
    protected static ?int $navigationSort = 10;
    protected static ?string $title = 'Election Settings';
    protected static ?string $navigationLabel = 'Settings';

    public static function canAccess(): bool
    {
        return Filament::getTenant()?->hasModule('elections') ?? false;
    }

    public ?array $data = [];

    public function mount(): void
    {
        $association = Filament::getTenant();
        $settings = ElectionSetting::firstOrCreate(
            ['association_id' => $association->id],
            [
                'default_voting_strategy' => 'plurality',
                'default_voting_method' => 'online',
                'default_timezone' => 'Africa/Lagos',
                'default_quorum_percentage' => 0,
                'default_tie_breaking_rule' => 'runoff',
                'default_required_certifiers' => 1,
                'allow_self_nomination' => true,
                'require_endorsements' => false,
                'min_endorsements' => 0,
                'send_otp_for_voting' => false,
            ]
        );

        $this->form->fill($settings->toArray());
    }

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                Section::make('Default Voting Configuration')
                    ->description('These defaults will be pre-filled when creating new elections.')
                    ->icon('heroicon-o-hand-raised')
                    ->schema([
                        Grid::make(3)->schema([
                            Select::make('default_voting_strategy')
                                ->label('Default Voting Strategy')
                                ->options(Election::STRATEGIES)
                                ->default('plurality')
                                ->required(),
                            Select::make('default_voting_method')
                                ->label('Default Voting Method')
                                ->options(Election::METHODS)
                                ->default('online')
                                ->required(),
                            Select::make('default_timezone')
                                ->label('Default Timezone')
                                ->options(collect(timezone_identifiers_list())
                                    ->mapWithKeys(fn ($tz) => [$tz => $tz]))
                                ->default('Africa/Lagos')
                                ->searchable()
                                ->required(),
                        ]),
                    ]),

                Section::make('Governance Defaults')
                    ->description('Default governance settings for new elections.')
                    ->icon('heroicon-o-building-library')
                    ->schema([
                        Grid::make(3)->schema([
                            TextInput::make('default_quorum_percentage')
                                ->label('Default Quorum (%)')
                                ->numeric()
                                ->minValue(0)
                                ->maxValue(100)
                                ->suffix('%')
                                ->default(0)
                                ->helperText('0 = no quorum requirement'),
                            Select::make('default_tie_breaking_rule')
                                ->label('Default Tie-Breaking Rule')
                                ->options(Election::TIE_BREAKING_RULES)
                                ->default('runoff'),
                            TextInput::make('default_required_certifiers')
                                ->label('Default Required Certifiers')
                                ->numeric()
                                ->minValue(1)
                                ->maxValue(10)
                                ->default(1),
                        ]),
                    ]),

                Section::make('Nomination Settings')
                    ->description('Control how candidates are nominated for elections.')
                    ->icon('heroicon-o-user-plus')
                    ->schema([
                        Grid::make(3)->schema([
                            Toggle::make('allow_self_nomination')
                                ->label('Allow Self-Nomination')
                                ->helperText('Members can nominate themselves for positions')
                                ->default(true),
                            Toggle::make('require_endorsements')
                                ->label('Require Endorsements')
                                ->helperText('Candidates must receive endorsements')
                                ->default(false)
                                ->live(),
                            TextInput::make('min_endorsements')
                                ->label('Minimum Endorsements Required')
                                ->numeric()
                                ->minValue(0)
                                ->default(0)
                                ->visible(fn ($get) => $get('require_endorsements')),
                        ]),
                    ]),

                Section::make('Security & Verification')
                    ->description('Default security settings for voting.')
                    ->icon('heroicon-o-shield-check')
                    ->schema([
                        Toggle::make('send_otp_for_voting')
                            ->label('Require OTP for Voting')
                            ->helperText('Voters must verify via email OTP before casting their ballot (applies to all new elections)')
                            ->default(false),
                    ]),

                Section::make('Default Voter Eligibility')
                    ->description('Default eligibility criteria applied to new elections.')
                    ->icon('heroicon-o-check-badge')
                    ->collapsible()
                    ->collapsed()
                    ->schema([
                        Grid::make(2)->schema([
                            Toggle::make('default_voter_eligibility.require_dues_current')
                                ->label('Require Dues to Be Current')
                                ->default(false),
                            TextInput::make('default_voter_eligibility.min_membership_months')
                                ->label('Minimum Membership (Months)')
                                ->numeric()
                                ->minValue(0)
                                ->default(0),
                        ]),
                    ]),

                Section::make('Default Candidate Eligibility')
                    ->description('Default eligibility criteria for candidates in new elections.')
                    ->icon('heroicon-o-user-circle')
                    ->collapsible()
                    ->collapsed()
                    ->schema([
                        Grid::make(2)->schema([
                            Toggle::make('default_candidate_eligibility.require_dues_current')
                                ->label('Require Dues to Be Current')
                                ->default(false),
                            TextInput::make('default_candidate_eligibility.min_membership_months')
                                ->label('Minimum Membership (Months)')
                                ->numeric()
                                ->minValue(0)
                                ->default(0),
                        ]),
                    ]),

                Section::make('Default Voting Rules')
                    ->description('Default ballot rules applied to new elections.')
                    ->icon('heroicon-o-cog-6-tooth')
                    ->collapsible()
                    ->collapsed()
                    ->schema([
                        Grid::make(2)->schema([
                            Toggle::make('default_voting_rules.anonymous')
                                ->label('Anonymous Voting')
                                ->helperText('Votes cannot be traced back to voters')
                                ->default(false),
                            Toggle::make('default_voting_rules.token_burn')
                                ->label('Token-Burn Anonymity')
                                ->helperText('Cryptographically sever identity-to-vote link')
                                ->default(false),
                            Toggle::make('default_voting_rules.otp_required')
                                ->label('Require OTP Verification')
                                ->default(false),
                            Toggle::make('default_voting_rules.ip_restriction')
                                ->label('One Vote per IP Address')
                                ->default(false),
                        ]),
                    ]),
            ])
            ->statePath('data');
    }

    protected function getFormActions(): array
    {
        return [
            Action::make('save')
                ->label('Save Election Settings')
                ->submit('save'),
        ];
    }

    public function save(): void
    {
        try {
            $data = $this->form->getState();
            $association = Filament::getTenant();

            ElectionSetting::updateOrCreate(
                ['association_id' => $association->id],
                $data
            );

            Notification::make()
                ->success()
                ->title('Election Settings Saved')
                ->body('Default election settings have been updated successfully.')
                ->send();
        } catch (\Exception $exception) {
            Notification::make()
                ->danger()
                ->title('Error Saving Settings')
                ->body($exception->getMessage())
                ->send();
        }
    }
}
