<?php

namespace App\Services\Settings;

use App\Enums\AppointmentStatus;
use App\Models\Business;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;

class SettingsService
{
    public function pages(): array
    {
        return [
            'business' => ['group' => 'business', 'view' => 'admin.settings.business'],
            'booking' => ['group' => 'booking', 'view' => 'admin.settings.booking'],
            'staff-services' => ['group' => 'staff_service', 'view' => 'admin.settings.staff-services'],
            'invoices' => ['group' => 'invoice', 'view' => 'admin.settings.invoices'],
            'notifications' => ['group' => 'notification', 'view' => 'admin.settings.notifications'],
            'whatsapp' => ['group' => 'whatsapp', 'view' => 'admin.settings.whatsapp'],
            'email-smtp' => ['group' => 'email_smtp', 'view' => 'admin.settings.email-smtp'],
            'branding' => ['group' => 'branding', 'view' => 'admin.settings.branding'],
            'localization' => ['group' => 'localization', 'view' => 'admin.settings.localization'],
            'security' => ['group' => 'security', 'view' => 'admin.settings.security'],
            'billing' => ['group' => 'billing', 'view' => 'admin.settings.billing'],
        ];
    }

    public function normalizePage(?string $page): string
    {
        $page = $page ?: 'business';

        abort_unless(array_key_exists($page, $this->pages()), 404);

        return $page;
    }

    public function viewFor(string $page): string
    {
        return $this->pages()[$this->normalizePage($page)]['view'];
    }

    public function groupFor(string $page): string
    {
        return $this->pages()[$this->normalizePage($page)]['group'];
    }

    public function routeNameFor(string $page): string
    {
        return match ($this->normalizePage($page)) {
            'business' => 'admin.settings.business',
            'booking' => 'admin.settings.booking',
            'staff-services' => 'admin.settings.staff-services',
            'invoices' => 'admin.settings.invoices',
            'notifications' => 'admin.settings.notifications',
            'whatsapp' => 'admin.settings.whatsapp',
            'email-smtp' => 'admin.settings.email-smtp',
            'branding' => 'admin.settings.branding',
            'localization' => 'admin.settings.localization',
            'security' => 'admin.settings.security',
            'billing' => 'admin.settings.billing',
        };
    }

    public function editData(Business $business, string $page): array
    {
        $page = $this->normalizePage($page);
        $settings = $this->get($business, $page);

        return [
            'activeTab' => $page,
            'intro' => $this->intro($page),
            'sections' => $this->sections($business, $page, $settings),
            'settings' => $settings,
            'formAction' => $this->updateRoute($page),
        ];
    }

    public function get(Business $business, string $page, bool $revealSecrets = false): array
    {
        $page = $this->normalizePage($page);
        $settings = $this->defaults($business, $page);
        $secretConfigured = [];

        Setting::query()
            ->forBusiness($business)
            ->where('group', $this->groupFor($page))
            ->get()
            ->each(function (Setting $setting) use (&$settings, &$secretConfigured, $revealSecrets): void {
                $key = $setting->name;
                $value = $this->storedValue($setting);

                if ($setting->is_encrypted) {
                    $secretConfigured[$key] = filled($value);
                    $value = $revealSecrets ? $value : null;
                }

                $settings[$key] = $value;
            });

        $settings['_secret_configured'] = $secretConfigured;

        return $settings;
    }

    public function defaults(Business $business, string $page): array
    {
        return match ($this->normalizePage($page)) {
            'business' => [
                'business_name' => $business->name,
                'owner_name' => $business->owner?->name ?? '',
                'logo_path' => $business->logo_path ?: 'booklio-logo.png',
                'cover_path' => $business->cover_path ?: 'salon-cover.jpg',
                'email' => $business->email ?: 'hello@booklio.test',
                'phone' => $business->phone ?: '+1 (555) 900-1200',
                'website' => $business->website ?: 'https://booklio.test',
                'address' => $business->address ?: '128 Market Street, San Francisco, CA',
                'business_description' => $business->description ?: 'Premium salon services with easy online appointment booking.',
            ],
            'booking' => [
                'booking_slug' => $business->slug,
                'default_status' => AppointmentStatus::Pending->value,
                'auto_confirm_bookings' => true,
                'allow_staff_selection' => true,
                'minimum_advance_minutes' => 120,
                'maximum_advance_days' => 60,
                'slot_interval' => 15,
                'cancellation_window_hours' => 24,
            ],
            'staff-services' => [
                'default_duration_minutes' => 60,
                'buffer_before_minutes' => 10,
                'buffer_after_minutes' => 10,
                'allow_staff_breaks' => true,
                'allow_multiple_staff_per_service' => true,
            ],
            'invoices' => [
                'invoice_prefix' => 'INV',
                'next_invoice_number' => 1030,
                'tax_name' => 'Sales Tax',
                'tax_percentage' => 8,
                'default_due_days' => 7,
                'show_business_logo' => true,
                'invoice_footer' => 'Thank you for choosing '.$business->name.'.',
            ],
            'notifications' => [
                'enable_booking_confirmation' => true,
                'enable_appointment_reminder' => true,
                'enable_cancellation_notification' => true,
                'enable_invoice_reminder' => true,
                'appointment_reminder_hours' => 24,
                'follow_up_hours' => 2,
            ],
            'whatsapp' => [
                'enabled' => true,
                'phone_number_id' => '109876543210987',
                'business_account_id' => '987654321098765',
                'access_token' => null,
                'webhook_verify_token' => null,
                'test_phone_number' => '+1 555 123 4567',
            ],
            'email-smtp' => [
                'smtp_host' => 'smtp.mailprovider.com',
                'smtp_port' => 587,
                'smtp_username' => 'notifications@booklio.test',
                'smtp_password' => null,
                'encryption' => 'tls',
                'from_email' => $business->email ?: 'hello@booklio.test',
                'from_name' => $business->name,
                'test_email' => $business->owner?->email ?? 'owner@booklio.test',
            ],
            'branding' => [
                'primary_color' => '#2563EB',
                'secondary_color' => '#0EA5E9',
                'logo_path' => $business->logo_path ?: 'booklio-logo.png',
                'favicon_path' => 'favicon.ico',
                'public_theme' => 'clean',
                'custom_footer' => 'Powered by Booklio. Thank you for booking with us.',
            ],
            'localization' => [
                'default_language' => 'en',
                'timezone' => $business->timezone ?: 'America/Los_Angeles',
                'date_format' => 'M d, Y',
                'time_format' => '12',
                'currency' => $business->currency ?: 'USD',
                'currency_position' => 'before',
                'first_day' => 'monday',
                'enable_english' => true,
                'enable_arabic' => true,
                'enable_urdu' => true,
                'new_language_direction' => 'ltr',
            ],
            'security' => [
                'current_password' => null,
                'new_password' => null,
                'two_factor_enabled' => false,
                'session_timeout' => '60',
                'activity_log_enabled' => true,
            ],
            'billing' => [
                'plan_limits' => '10 staff / unlimited bookings',
                'billing_cycle' => 'monthly',
            ],
        };
    }

    public function save(Business $business, string $page, array $payload, ?User $user = null): void
    {
        $page = $this->normalizePage($page);
        $group = $this->groupFor($page);

        if ($page === 'security' && filled($payload['new_password'] ?? null)) {
            if (! $user || ! Hash::check((string) ($payload['current_password'] ?? ''), $user->password)) {
                throw ValidationException::withMessages([
                    'current_password' => 'The current password is incorrect.',
                ]);
            }

            $user->forceFill(['password' => $payload['new_password']])->save();
        }

        foreach ($payload as $key => $value) {
            if (in_array($key, ['current_password', 'new_password'], true)) {
                continue;
            }

            if (! array_key_exists($key, $this->defaults($business, $page))) {
                continue;
            }

            if ($this->isSecret($page, $key)) {
                if (! filled($value)) {
                    continue;
                }

                $this->put($business, $group, $key, Crypt::encryptString((string) $value), true);

                continue;
            }

            $this->put($business, $group, $key, $value, false);
        }

        $this->syncBusinessColumns($business, $page, $payload);
    }

    public function rules(Business $business, string $page): array
    {
        return match ($this->normalizePage($page)) {
            'business' => [
                'business_name' => ['required', 'string', 'max:150'],
                'owner_name' => ['required', 'string', 'max:150'],
                'logo_path' => ['nullable', 'string', 'max:255'],
                'cover_path' => ['nullable', 'string', 'max:255'],
                'email' => ['nullable', 'email', 'max:150'],
                'phone' => ['nullable', 'string', 'max:60'],
                'website' => ['nullable', 'url', 'max:255'],
                'address' => ['nullable', 'string', 'max:1000'],
                'business_description' => ['nullable', 'string', 'max:2000'],
            ],
            'booking' => [
                'booking_slug' => ['required', 'alpha_dash', 'max:120'],
                'default_status' => ['required', 'in:pending,confirmed,checked_in'],
                'auto_confirm_bookings' => ['boolean'],
                'allow_staff_selection' => ['boolean'],
                'minimum_advance_minutes' => ['required', 'integer', 'min:0', 'max:10080'],
                'maximum_advance_days' => ['required', 'integer', 'min:1', 'max:365'],
                'slot_interval' => ['required', 'integer', 'min:5', 'max:240'],
                'cancellation_window_hours' => ['required', 'integer', 'min:0', 'max:720'],
            ],
            'staff-services' => [
                'default_duration_minutes' => ['required', 'integer', 'min:5', 'max:1440'],
                'buffer_before_minutes' => ['required', 'integer', 'min:0', 'max:240'],
                'buffer_after_minutes' => ['required', 'integer', 'min:0', 'max:240'],
                'allow_staff_breaks' => ['boolean'],
                'allow_multiple_staff_per_service' => ['boolean'],
            ],
            'invoices' => [
                'invoice_prefix' => ['required', 'string', 'max:20'],
                'next_invoice_number' => ['required', 'integer', 'min:1', 'max:999999999'],
                'tax_name' => ['nullable', 'string', 'max:80'],
                'tax_percentage' => ['nullable', 'numeric', 'min:0', 'max:100'],
                'default_due_days' => ['required', 'integer', 'min:0', 'max:365'],
                'show_business_logo' => ['boolean'],
                'invoice_footer' => ['nullable', 'string', 'max:2000'],
            ],
            'notifications' => [
                'enable_booking_confirmation' => ['boolean'],
                'enable_appointment_reminder' => ['boolean'],
                'enable_cancellation_notification' => ['boolean'],
                'enable_invoice_reminder' => ['boolean'],
                'appointment_reminder_hours' => ['required', 'integer', 'min:0', 'max:720'],
                'follow_up_hours' => ['required', 'integer', 'min:0', 'max:720'],
            ],
            'whatsapp' => [
                'enabled' => ['boolean'],
                'phone_number_id' => ['nullable', 'string', 'max:120'],
                'business_account_id' => ['nullable', 'string', 'max:120'],
                'access_token' => ['nullable', 'string', 'max:1000'],
                'webhook_verify_token' => ['nullable', 'string', 'max:255'],
                'test_phone_number' => ['nullable', 'string', 'max:60'],
            ],
            'email-smtp' => [
                'smtp_host' => ['required', 'string', 'max:150'],
                'smtp_port' => ['required', 'integer', 'min:1', 'max:65535'],
                'smtp_username' => ['nullable', 'string', 'max:150'],
                'smtp_password' => ['nullable', 'string', 'max:255'],
                'encryption' => ['required', 'in:tls,ssl,none'],
                'from_email' => ['required', 'email', 'max:150'],
                'from_name' => ['required', 'string', 'max:150'],
                'test_email' => ['nullable', 'email', 'max:150'],
            ],
            'branding' => [
                'primary_color' => ['required', 'regex:/^#[0-9A-Fa-f]{6}$/'],
                'secondary_color' => ['required', 'regex:/^#[0-9A-Fa-f]{6}$/'],
                'logo_path' => ['nullable', 'string', 'max:255'],
                'favicon_path' => ['nullable', 'string', 'max:255'],
                'public_theme' => ['required', 'in:clean,premium,minimal'],
                'custom_footer' => ['nullable', 'string', 'max:500'],
            ],
            'localization' => [
                'default_language' => ['required', 'string', 'max:12'],
                'timezone' => ['required', 'timezone'],
                'date_format' => ['required', 'in:M d, Y,d/m/Y,Y-m-d'],
                'time_format' => ['required', 'in:12,24'],
                'currency' => ['required', 'string', 'size:3'],
                'currency_position' => ['required', 'in:before,after'],
                'first_day' => ['required', 'in:monday,sunday,saturday'],
                'enable_english' => ['boolean'],
                'enable_arabic' => ['boolean'],
                'enable_urdu' => ['boolean'],
                'new_language_direction' => ['required', 'in:ltr,rtl'],
            ],
            'security' => [
                'current_password' => ['nullable', 'string', 'max:255'],
                'new_password' => ['nullable', 'string', 'min:8', 'max:255'],
                'two_factor_enabled' => ['boolean'],
                'session_timeout' => ['required', 'in:30,60,240,1440'],
                'activity_log_enabled' => ['boolean'],
            ],
            'billing' => [
                'plan_limits' => ['nullable', 'string', 'max:255'],
                'billing_cycle' => ['required', 'in:monthly,yearly'],
            ],
        };
    }

    public function booleanFields(string $page): array
    {
        return match ($this->normalizePage($page)) {
            'booking' => ['auto_confirm_bookings', 'allow_staff_selection'],
            'staff-services' => ['allow_staff_breaks', 'allow_multiple_staff_per_service'],
            'invoices' => ['show_business_logo'],
            'notifications' => ['enable_booking_confirmation', 'enable_appointment_reminder', 'enable_cancellation_notification', 'enable_invoice_reminder'],
            'whatsapp' => ['enabled'],
            'localization' => ['enable_english', 'enable_arabic', 'enable_urdu'],
            'security' => ['two_factor_enabled', 'activity_log_enabled'],
            default => [],
        };
    }

    public function secretConfigured(array $settings, string $key): bool
    {
        return (bool) data_get($settings, '_secret_configured.'.$key, false);
    }

    private function intro(string $page): string
    {
        return match ($page) {
            'business' => 'Keep your public booking page, invoices, and customer messages aligned with your business identity.',
            'booking' => 'Control how customers book appointments from the public booking page.',
            'staff-services' => 'Set sensible defaults for services, staff assignment, breaks, and appointment spacing.',
            'invoices' => 'Configure invoice numbering, tax display, due dates, and customer-facing invoice notes.',
            'notifications' => 'Control which customer notifications are sent automatically after key booking events.',
            'whatsapp' => 'Connect WhatsApp Business API so Booklio can send customer reminders automatically.',
            'email-smtp' => 'Configure SMTP credentials for confirmation emails, invoice reminders, and follow-up messages.',
            'branding' => "Customize Booklio's public booking page so it matches your brand.",
            'localization' => 'Make dates, times, currency, and language feel familiar to customers and staff.',
            'security' => 'Keep business owner and staff accounts protected with simple security controls.',
            'billing' => 'Review your current plan, billing cycle, plan limits, and payment history.',
        };
    }

    private function sections(Business $business, string $page, array $settings): array
    {
        return match ($page) {
            'business' => [[
                'title' => 'Business Profile',
                'description' => 'This information appears on your booking page, customer invoices, and notifications.',
                'fields' => [
                    $this->input('business_name', 'Business name', $settings, 'Use the name your customers recognize.'),
                    $this->input('owner_name', 'Owner name', $settings),
                    $this->upload('logo_path', 'Business logo', $settings, 'Recommended size: 512 x 512px.'),
                    $this->upload('cover_path', 'Cover image', $settings, 'Wide image for your public booking page header.'),
                    $this->input('email', 'Email', $settings, null, 'email'),
                    $this->input('phone', 'Phone', $settings),
                    $this->input('website', 'Website', $settings),
                    $this->input('address', 'Address', $settings, null, 'text', true),
                    $this->textarea('business_description', 'Business description', $settings, 'Short and friendly text for your public booking page.', true),
                ],
            ]],
            'booking' => [[
                'title' => 'Booking Rules',
                'description' => 'Set customer-facing booking behavior and appointment timing rules.',
                'fields' => [
                    $this->input('booking_slug', 'Booking page slug', $settings, 'Example: booklio.com/book/'.$business->slug),
                    $this->select('default_status', 'Default appointment status', $settings, ['pending' => 'Pending', 'confirmed' => 'Confirmed', 'checked_in' => 'Checked In']),
                    $this->toggle('auto_confirm_bookings', 'Auto-confirm bookings', $settings, 'Automatically confirm appointments after customers book online.'),
                    $this->toggle('allow_staff_selection', 'Allow staff selection', $settings, 'Customers can choose a preferred staff member.'),
                    $this->input('minimum_advance_minutes', 'Minimum advance booking time', $settings, 'Minutes before an appointment starts.', 'number'),
                    $this->input('maximum_advance_days', 'Maximum advance booking days', $settings, null, 'number'),
                    $this->input('slot_interval', 'Booking slot interval', $settings, 'Minutes between public booking slots.', 'number'),
                    $this->input('cancellation_window_hours', 'Cancellation window', $settings, 'Hours before start time.', 'number'),
                ],
            ]],
            'staff-services' => [[
                'title' => 'Service Defaults',
                'description' => 'These defaults are used when owners create new services or staff schedules.',
                'fields' => [
                    $this->input('default_duration_minutes', 'Default service duration', $settings, null, 'number'),
                    $this->input('buffer_before_minutes', 'Buffer time before appointment', $settings, null, 'number'),
                    $this->input('buffer_after_minutes', 'Buffer time after appointment', $settings, null, 'number'),
                    $this->toggle('allow_staff_breaks', 'Allow staff breaks', $settings, 'Let staff add break times inside working hours.'),
                    $this->toggle('allow_multiple_staff_per_service', 'Allow multiple staff per service', $settings, 'Useful for services that can be performed by more than one staff member.', true),
                ],
            ]],
            'invoices' => [[
                'title' => 'Invoice Defaults',
                'description' => 'These values are applied to new invoices and PDF previews.',
                'fields' => [
                    $this->input('invoice_prefix', 'Invoice prefix', $settings),
                    $this->input('next_invoice_number', 'Next invoice number', $settings, null, 'number'),
                    $this->input('tax_name', 'Tax name', $settings),
                    $this->input('tax_percentage', 'Tax percentage', $settings, null, 'number'),
                    $this->input('default_due_days', 'Default due days', $settings, null, 'number'),
                    $this->toggle('show_business_logo', 'Show business logo on invoice', $settings, 'Display your logo at the top of invoice PDFs.'),
                    $this->textarea('invoice_footer', 'Invoice footer note', $settings, null, true),
                ],
            ]],
            'notifications' => [[
                'title' => 'Notification Automation',
                'description' => 'Keep customers informed without manual follow-up.',
                'fields' => [
                    $this->toggle('enable_booking_confirmation', 'Enable booking confirmation', $settings, 'Send confirmation after a booking is created.'),
                    $this->toggle('enable_appointment_reminder', 'Enable appointment reminder', $settings, 'Remind customers before their appointment.'),
                    $this->toggle('enable_cancellation_notification', 'Enable cancellation notification', $settings, 'Notify customers when an appointment is cancelled.'),
                    $this->toggle('enable_invoice_reminder', 'Enable invoice reminder', $settings, 'Send reminders for unpaid invoices.'),
                    $this->input('appointment_reminder_hours', 'Reminder time before appointment', $settings, 'Hours before appointment.', 'number'),
                    $this->input('follow_up_hours', 'Follow-up message after completion', $settings, 'Hours after completion.', 'number'),
                ],
            ]],
            'whatsapp' => [[
                'title' => 'WhatsApp Business API',
                'description' => 'Credentials are stored securely. Real API sending will be connected in the reminders phase.',
                'fields' => [
                    $this->toggle('enabled', 'Enable WhatsApp reminders', $settings, 'Send booking and invoice reminders through WhatsApp.', true),
                    $this->input('phone_number_id', 'Phone Number ID', $settings),
                    $this->input('business_account_id', 'Business Account ID', $settings),
                    $this->secret('access_token', 'Access Token', $settings),
                    $this->secret('webhook_verify_token', 'Webhook Verify Token', $settings),
                    $this->input('test_phone_number', 'Test message field', $settings, 'Enter a phone number to test delivery.'),
                    $this->notice('Send test message', 'Use this area later to send a test WhatsApp message after credentials are connected.', true),
                ],
            ]],
            'email-smtp' => [[
                'title' => 'SMTP Configuration',
                'description' => 'Use your email provider settings. Secrets are encrypted in storage.',
                'fields' => [
                    $this->input('smtp_host', 'SMTP host', $settings),
                    $this->input('smtp_port', 'SMTP port', $settings, null, 'number'),
                    $this->input('smtp_username', 'SMTP username', $settings),
                    $this->secret('smtp_password', 'SMTP password', $settings),
                    $this->select('encryption', 'Encryption', $settings, ['tls' => 'TLS', 'ssl' => 'SSL', 'none' => 'None']),
                    $this->input('from_email', 'From email', $settings, null, 'email'),
                    $this->input('from_name', 'From name', $settings),
                    $this->input('test_email', 'Test email field', $settings, 'Enter an email address for a test message.', 'email'),
                ],
            ]],
            'branding' => [[
                'title' => 'Brand Appearance',
                'description' => 'Colors, logos, and public page theme used by customers.',
                'fields' => [
                    $this->color('primary_color', 'Primary color picker', $settings, 'Used for primary buttons and active states.'),
                    $this->color('secondary_color', 'Secondary color picker', $settings, 'Used for accents and highlights.'),
                    $this->upload('logo_path', 'Business logo', $settings),
                    $this->upload('favicon_path', 'Favicon', $settings),
                    $this->select('public_theme', 'Public booking page theme', $settings, ['clean' => 'Clean Light', 'premium' => 'Premium Blue', 'minimal' => 'Minimal White']),
                    $this->textarea('custom_footer', 'Custom footer text', $settings, null, true),
                ],
            ]],
            'localization' => [[
                'title' => 'Regional Preferences',
                'description' => 'These defaults affect calendars, invoices, booking pages, and reports.',
                'fields' => [
                    $this->select('default_language', 'Default language', $settings, ['en' => 'English', 'ar' => 'Arabic', 'ur' => 'Urdu']),
                    $this->select('timezone', 'Timezone', $settings, ['America/Los_Angeles' => 'Pacific Time', 'America/New_York' => 'Eastern Time', 'Asia/Karachi' => 'Asia/Karachi']),
                    $this->select('date_format', 'Date format', $settings, ['M d, Y' => 'May 22, 2026', 'd/m/Y' => '22/05/2026', 'Y-m-d' => '2026-05-22']),
                    $this->select('time_format', 'Time format', $settings, ['12' => '12-hour', '24' => '24-hour']),
                    $this->select('currency', 'Currency', $settings, ['USD' => 'USD', 'EUR' => 'EUR', 'GBP' => 'GBP', 'PKR' => 'PKR']),
                    $this->select('currency_position', 'Currency position', $settings, ['before' => 'Before amount ($100)', 'after' => 'After amount (100 $)']),
                    $this->select('first_day', 'First day of week', $settings, ['monday' => 'Monday', 'sunday' => 'Sunday', 'saturday' => 'Saturday']),
                ],
            ], [
                'title' => 'Language Management',
                'description' => 'Demo controls for managing languages and dashboard translation text.',
                'fields' => [
                    $this->toggle('enable_english', 'Enable English', $settings, 'LTR demo language available in the language dropdown.'),
                    $this->toggle('enable_arabic', 'Enable Arabic', $settings, 'RTL demo language. Selecting it flips the dashboard direction.'),
                    $this->toggle('enable_urdu', 'Enable Urdu', $settings, 'RTL demo language. Selecting it flips the dashboard direction.'),
                    $this->select('new_language_direction', 'Direction for added languages', $settings, ['ltr' => 'LTR', 'rtl' => 'RTL']),
                    $this->action('Add New Language', 'Placeholder for adding custom languages with code, name, enabled status, and LTR/RTL direction.', 'Add Language', true),
                    $this->notice('Translation text management placeholder', 'A translation editor will let owners update labels, navigation text, emails, reminders, and public booking page copy per language.', true),
                ],
            ]],
            'security' => [[
                'title' => 'Account Security',
                'description' => 'Password changes update the authenticated user. Other controls are saved as business security preferences.',
                'fields' => [
                    $this->input('current_password', 'Current password', $settings, 'Required only when changing password.', 'password'),
                    $this->input('new_password', 'New password', $settings, 'Leave blank to keep the current password.', 'password'),
                    $this->toggle('two_factor_enabled', 'Two-factor authentication placeholder', $settings, 'Add a second step to sign in for owners and staff.', true),
                    $this->select('session_timeout', 'Login session timeout', $settings, ['30' => '30 minutes', '60' => '1 hour', '240' => '4 hours', '1440' => '1 day']),
                    $this->toggle('activity_log_enabled', 'Activity log', $settings, 'Track important actions such as bookings, invoices, and setting changes.'),
                ],
            ]],
            'billing' => [[
                'title' => 'Current Subscription',
                'description' => 'Saved display preferences for subscription billing screens. Real plan state will come from subscriptions.',
                'fields' => [
                    $this->notice('Current plan: Pro Plan', 'Includes 10 staff, unlimited services, invoices, WhatsApp reminders, and advanced reports.', true),
                    $this->input('plan_limits', 'Plan limits', $settings),
                    $this->select('billing_cycle', 'Billing cycle', $settings, ['monthly' => 'Monthly', 'yearly' => 'Yearly']),
                    $this->action('Upgrade plan button', 'Open the plan selection screen to compare limits, billing cycles, and premium features.', 'Upgrade Plan', true),
                    $this->notice('Payment history placeholder', 'Recent payments will appear here with invoice numbers, dates, status, and downloadable receipts.', true),
                ],
            ]],
        };
    }

    private function updateRoute(string $page): string
    {
        return route($this->routeNameFor($page).'.update');
    }

    private function input(string $name, string $label, array $settings, ?string $help = null, string $type = 'text', bool $span = false): array
    {
        return compact('name', 'label', 'help', 'type', 'span') + ['value' => $settings[$name] ?? null];
    }

    private function textarea(string $name, string $label, array $settings, ?string $help = null, bool $span = false, int $rows = 4): array
    {
        return compact('name', 'label', 'help', 'span', 'rows') + ['type' => 'textarea', 'value' => $settings[$name] ?? null];
    }

    private function select(string $name, string $label, array $settings, array $options, ?string $help = null, bool $span = false): array
    {
        return compact('name', 'label', 'options', 'help', 'span') + ['type' => 'select', 'value' => $settings[$name] ?? null];
    }

    private function toggle(string $name, string $label, array $settings, ?string $help = null, bool $span = false): array
    {
        return compact('name', 'label', 'help', 'span') + ['type' => 'toggle', 'checked' => (bool) ($settings[$name] ?? false)];
    }

    private function upload(string $name, string $label, array $settings, ?string $help = null, bool $span = false): array
    {
        return compact('name', 'label', 'help', 'span') + ['type' => 'upload', 'value' => $settings[$name] ?? null];
    }

    private function color(string $name, string $label, array $settings, ?string $help = null, bool $span = false): array
    {
        return compact('name', 'label', 'help', 'span') + ['type' => 'color', 'value' => $settings[$name] ?? '#2563EB'];
    }

    private function secret(string $name, string $label, array $settings, ?string $help = null, bool $span = false): array
    {
        return compact('name', 'label', 'help', 'span') + [
            'type' => 'password',
            'value' => null,
            'secret' => true,
            'configured' => $this->secretConfigured($settings, $name),
        ];
    }

    private function notice(string $label, string $help, bool $span = false): array
    {
        return compact('label', 'help', 'span') + ['type' => 'notice'];
    }

    private function action(string $label, string $help, string $button, bool $span = false): array
    {
        return compact('label', 'help', 'button', 'span') + ['type' => 'action'];
    }

    private function put(Business $business, string $group, string $name, mixed $value, bool $encrypted): void
    {
        Setting::query()->updateOrCreate(
            ['business_id' => $business->id, 'group' => $group, 'name' => $name],
            ['value' => $value, 'is_encrypted' => $encrypted]
        );
    }

    private function storedValue(Setting $setting): mixed
    {
        $value = $setting->value;

        if (is_array($value) && array_key_exists('value', $value) && count($value) === 1) {
            $value = $value['value'];
        }

        if (! $setting->is_encrypted || ! filled($value)) {
            return $value;
        }

        try {
            return Crypt::decryptString((string) $value);
        } catch (DecryptException) {
            return null;
        }
    }

    private function isSecret(string $page, string $key): bool
    {
        return in_array($page.'.'.$key, [
            'whatsapp.access_token',
            'whatsapp.webhook_verify_token',
            'email-smtp.smtp_password',
        ], true);
    }

    private function syncBusinessColumns(Business $business, string $page, array $payload): void
    {
        if ($page === 'business') {
            $business->fill([
                'name' => $payload['business_name'],
                'email' => $payload['email'] ?? null,
                'phone' => $payload['phone'] ?? null,
                'website' => $payload['website'] ?? null,
                'logo_path' => $payload['logo_path'] ?? null,
                'cover_path' => $payload['cover_path'] ?? null,
                'address' => $payload['address'] ?? null,
                'description' => $payload['business_description'] ?? null,
            ])->save();

            if ($business->owner && filled($payload['owner_name'] ?? null)) {
                $business->owner->forceFill(['name' => $payload['owner_name']])->save();
            }
        }

        if ($page === 'booking' && filled($payload['booking_slug'] ?? null) && $payload['booking_slug'] !== $business->slug) {
            $slug = Str::slug((string) $payload['booking_slug']) ?: $business->slug;
            $business->forceFill(['slug' => Business::uniqueSlug($slug, $business->id)])->save();
        }

        if ($page === 'localization') {
            $business->forceFill([
                'timezone' => $payload['timezone'],
                'currency' => strtoupper((string) $payload['currency']),
            ])->save();
        }

        if ($page === 'branding') {
            $business->forceFill([
                'logo_path' => $payload['logo_path'] ?? $business->logo_path,
            ])->save();
        }
    }
}
