<?php

namespace Modules\Identity\Filament\Pages;

use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Actions;
use Filament\Schemas\Components\Form;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Illuminate\Support\Facades\Artisan;
use Modules\Shared\Support\EnvFileWriter;
use UnitEnum;

/**
 * Edits real env-backed config values (config('app.*'), config('booking.*'))
 * in place via EnvFileWriter, rather than introducing a parallel DB-backed
 * settings table — so BookingService and everything else that already reads
 * config('booking.*') keeps working unchanged (domain.md §2).
 *
 * Requires the .env file to be writable by the app process; if it isn't
 * (e.g. some production containers ship a read-only filesystem), saving
 * will throw and the admin needs to edit .env directly on that host instead.
 */
class ManageAppSettings extends Page
{
    protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCog6Tooth;

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

    protected static ?string $navigationLabel = 'App Settings';

    protected static ?string $title = 'App Settings';

    protected string $view = 'identity::filament.pages.manage-app-settings';

    /**
     * @var array<string, mixed>|null
     */
    public ?array $data = [];

    public static function canAccess(): bool
    {
        return auth()->user()?->can('manage_settings') ?? false;
    }

    public function mount(): void
    {
        $this->form->fill([
            'site_name' => config('app.name'),
            'support_email' => config('app.support_email'),
            'support_phone' => config('app.support_phone'),
            'timezone' => config('app.timezone'),
            'currency' => config('app.currency'),
            'front_seat_enabled' => (bool) config('booking.front_seat_enabled'),
            'front_seat_max_per_booking' => config('booking.front_seat_max_per_booking'),
            'back_seat_enabled' => (bool) config('booking.back_seat_enabled'),
            'back_seat_max_per_booking' => config('booking.back_seat_max_per_booking'),
            'whole_vehicle_enabled' => (bool) config('booking.whole_vehicle_enabled'),
            'whole_vehicle_max_per_booking' => config('booking.whole_vehicle_max_per_booking'),
            'booking_admin_emails' => config('booking.admin_emails'),
            'sms_enabled' => (bool) config('services.sms.enabled'),
            'sms_server' => config('services.sms.sms_poh.server'),
            'sms_token' => config('services.sms.sms_poh.token'),
            'sms_sender' => config('services.sms.sms_poh.sender'),
        ]);
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                Form::make([
                    Tabs::make('Settings')
                        ->tabs([
                            Tab::make('General')
                                ->schema([
                                    TextInput::make('site_name')
                                        ->label('Site Name')
                                        ->required()
                                        ->maxLength(255),
                                    TextInput::make('support_email')
                                        ->label('Support Email')
                                        ->email()
                                        ->maxLength(255),
                                    TextInput::make('support_phone')
                                        ->label('Support Phone')
                                        ->tel()
                                        ->maxLength(255),
                                    TextInput::make('timezone')
                                        ->label('Timezone')
                                        ->required()
                                        ->maxLength(64)
                                        ->helperText('A valid PHP timezone identifier, e.g. Asia/Yangon.'),
                                    TextInput::make('currency')
                                        ->label('Currency Code')
                                        ->required()
                                        ->maxLength(3)
                                        ->helperText('ISO 4217 currency code, e.g. MMK.'),
                                ])
                                ->columns(2),
                            Tab::make('Booking')
                                ->schema([
                                    Toggle::make('front_seat_enabled')
                                        ->label('Front Seat Enabled')
                                        ->helperText('Whether customers can select Front Seat at all right now.'),
                                    TextInput::make('front_seat_max_per_booking')
                                        ->label('Front Seat Max Per Booking')
                                        ->numeric()
                                        ->minValue(1)
                                        ->required()
                                        ->helperText('Max Front Seats a single booking may request.'),
                                    Toggle::make('back_seat_enabled')
                                        ->label('Back Seat Enabled')
                                        ->helperText('Whether customers can select Back Seat at all right now.'),
                                    TextInput::make('back_seat_max_per_booking')
                                        ->label('Back Seat Max Per Booking')
                                        ->numeric()
                                        ->minValue(1)
                                        ->required()
                                        ->helperText('Max Back Seats a single booking may request.'),
                                    Toggle::make('whole_vehicle_enabled')
                                        ->label('Whole Vehicle Enabled')
                                        ->helperText('Whether customers can select Whole Vehicle at all right now.'),
                                    TextInput::make('whole_vehicle_max_per_booking')
                                        ->label('Whole Vehicle Max Per Booking')
                                        ->numeric()
                                        ->minValue(1)
                                        ->required()
                                        ->helperText('Max Whole Vehicle passenger count a single booking may request.'),
                                    TagsInput::make('booking_admin_emails')
                                        ->label('Admin Emails')
                                        ->required()
                                        ->helperText('Notified on booking events. Press enter after each address.'),
                                ])
                                ->columns(2),
                            Tab::make('SMS')
                                ->schema([
                                    Toggle::make('sms_enabled')
                                        ->label('SMS Enabled')
                                        ->live()
                                        ->helperText('Whether driver/car SMS notifications are sent at all.'),
                                    TextInput::make('sms_server')
                                        ->label('SMS Server URL')
                                        ->url()
                                        ->maxLength(255)
                                        ->required(fn (Get $get): bool => (bool) $get('sms_enabled')),
                                    TextInput::make('sms_token')
                                        ->label('SMS Token')
                                        ->password()
                                        ->revealable()
                                        ->maxLength(255)
                                        ->required(fn (Get $get): bool => (bool) $get('sms_enabled')),
                                    TextInput::make('sms_sender')
                                        ->label('SMS Sender')
                                        ->maxLength(255)
                                        ->helperText('Default sender name/number for outgoing SMS.'),
                                ])
                                ->columns(2),
                        ]),
                ])
                    ->livewireSubmitHandler('save')
                    ->footer([
                        Actions::make([
                            Action::make('save')
                                ->submit('save')
                                ->keyBindings(['mod+s']),
                        ]),
                    ]),
            ])
            ->statePath('data');
    }

    public function save(EnvFileWriter $writer): void
    {
        $state = $this->form->getState();

        $writer->write([
            'APP_NAME' => $state['site_name'],
            'SUPPORT_EMAIL' => $state['support_email'],
            'SUPPORT_PHONE' => $state['support_phone'],
            'APP_TIMEZONE' => $state['timezone'],
            'APP_CURRENCY' => $state['currency'],
            'BOOKING_FRONT_SEAT_ENABLED' => (bool) $state['front_seat_enabled'],
            'BOOKING_FRONT_SEAT_MAX_PER_BOOKING' => (int) $state['front_seat_max_per_booking'],
            'BOOKING_BACK_SEAT_ENABLED' => (bool) $state['back_seat_enabled'],
            'BOOKING_BACK_SEAT_MAX_PER_BOOKING' => (int) $state['back_seat_max_per_booking'],
            'BOOKING_WHOLE_VEHICLE_ENABLED' => (bool) $state['whole_vehicle_enabled'],
            'BOOKING_WHOLE_VEHICLE_MAX_PER_BOOKING' => (int) $state['whole_vehicle_max_per_booking'],
            'BOOKING_ADMIN_EMAILS' => implode(',', $state['booking_admin_emails'] ?? []),
            'SMS_ENABLED' => (bool) $state['sms_enabled'],
            'SMS_SERVER' => $state['sms_server'],
            'SMS_TOKEN' => $state['sms_token'],
            'SMS_SENDER' => $state['sms_sender'],
        ]);

        Artisan::call('config:clear');

        Notification::make()
            ->title('Settings saved')
            ->success()
            ->send();
    }
}
