<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Filament\Pages;

use App\Filament\Concerns\InteractsWithDberpPermissions;
use App\Filament\Pages\Concerns\ManagesDberpSystemProfileForm;
use App\Filament\Resources\Concerns\HasDberpRegionAddress;
use App\Filament\Resources\Concerns\InteractsWithDberpRegionAddress;
use App\Models\DberpRegion;
use App\Services\DberpPermissionService;
use App\Services\Install\InstallWizardTimezoneOptions;
use App\Support\DberpCurrencySelectOptions;
use App\Support\DberpProductBranding;
use BackedEnum;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Pages\Page;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Illuminate\Contracts\Support\Htmlable;
use UnitEnum;

final class SystemBasicSettingsPage extends Page
{
    use HasDberpRegionAddress;
    use InteractsWithDberpPermissions;
    use InteractsWithDberpRegionAddress;
    use ManagesDberpSystemProfileForm;

    protected static ?string $slug = 'system-basic-settings';

    protected static ?int $navigationSort = 10;

    public static function getNavigationGroup(): string|UnitEnum|null
    {
        return __('dberp.nav.system');
    }

    public static function getNavigationLabel(): string
    {
        return __('dberp.labels.system_basic_settings');
    }

    public static function getNavigationIcon(): string|BackedEnum|Htmlable|null
    {
        return null;
    }

    public static function canAccess(): bool
    {
        return self::allowsPermission(DberpPermissionService::VIEW_SYSTEM_SETTINGS);
    }

    public function getTitle(): string|Htmlable
    {
        return __('dberp.labels.system_basic_settings');
    }

    /**
     * @return list<string>
     */
    protected function profileFieldNames(): array
    {
        return [
            'company_name',
            'system_display_name',
            'contact_phone',
            'contact_email',
            'address',
            'country_code',
            'region_id',
            'region_name_snapshot',
            'site_icp_record_no',
            'site_public_security_record_no',
            'default_currency_code',
            'display_timezone',
            'amount_decimal_places',
            'quantity_decimal_places',
        ];
    }

    protected function profileAuditAction(): string
    {
        return 'dberp.system_profile.basic_updated';
    }

    protected function getCurrentDberpRegion(): ?DberpRegion
    {
        $profile = $this->resolveSystemProfileRecord();
        $region = $profile->region;

        return $region instanceof DberpRegion ? $region : null;
    }

    /**
     * @param  array<string, mixed>  $data
     * @return array<string, mixed>
     */
    protected function mutateFormDataBeforeFill(array $data): array
    {
        $this->resolveSystemProfileRecord()->loadMissing('region');

        $currency = $data['default_currency_code'] ?? null;
        if (! is_string($currency) || trim($currency) === '') {
            $data['default_currency_code'] = DberpCurrencySelectOptions::defaultCode();
        } else {
            $data['default_currency_code'] = DberpCurrencySelectOptions::normalizeCode($currency)
                ?? DberpCurrencySelectOptions::defaultCode();
        }

        $branding = app(DberpProductBranding::class);
        if (! $branding->canCustomizeDisplayName()) {
            $data['system_display_name'] = $branding->defaultBrandName();
        }

        return $this->mutateDberpRegionFormDataBeforeFill($data);
    }

    /**
     * @param  array<string, mixed>  $data
     * @return array<string, mixed>
     */
    protected function mutateFormDataBeforeSave(array $data): array
    {
        if (array_key_exists('default_currency_code', $data)) {
            $raw = $data['default_currency_code'];
            $normalized = is_string($raw) ? DberpCurrencySelectOptions::normalizeCode($raw) : null;
            $data['default_currency_code'] = $normalized ?? DberpCurrencySelectOptions::defaultCode();
        }

        if (! app(DberpProductBranding::class)->canCustomizeDisplayName()) {
            unset($data['system_display_name']);
        }

        foreach (['site_icp_record_no', 'site_public_security_record_no'] as $field) {
            if (! array_key_exists($field, $data)) {
                continue;
            }

            $raw = $data[$field];
            $trimmed = is_string($raw) ? trim($raw) : '';
            $data[$field] = $trimmed === '' ? null : $trimmed;
        }

        return $this->mutateDberpRegionFormDataBeforePersist($data);
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make(__('dberp.sections.company_public'))
                    ->schema([
                        TextInput::make('company_name')
                            ->label(__('dberp.fields.company_name'))
                            ->maxLength(255),
                        TextInput::make('system_display_name')
                            ->label(__('dberp.fields.system_display_name'))
                            ->maxLength(255)
                            ->disabled(fn (): bool => ! app(DberpProductBranding::class)->canCustomizeDisplayName())
                            ->dehydrated(fn (): bool => app(DberpProductBranding::class)->canCustomizeDisplayName())
                            ->helperText(fn (): ?string => app(DberpProductBranding::class)->canCustomizeDisplayName()
                                ? null
                                : __('dberp.hints.system_display_name_requires_license')),
                        TextInput::make('contact_phone')
                            ->label(__('dberp.fields.contact_phone'))
                            ->tel()
                            ->maxLength(64),
                        TextInput::make('contact_email')
                            ->label(__('dberp.fields.contact_email'))
                            ->email()
                            ->maxLength(128),
                        ...self::getDberpRegionAddressFormFields(withHelperTexts: false),
                    ])
                    ->columns(2),
                Section::make(__('dberp.sections.filing_info'))
                    ->schema([
                        TextInput::make('site_icp_record_no')
                            ->label(__('dberp.fields.site_icp_record_no'))
                            ->maxLength(64)
                            ->trim(),
                        TextInput::make('site_public_security_record_no')
                            ->label(__('dberp.fields.site_public_security_record_no'))
                            ->maxLength(128)
                            ->trim(),
                    ])
                    ->columns(2),
                Section::make(__('dberp.sections.number_display_format'))
                    ->schema([
                        Select::make('display_timezone')
                            ->label(__('dberp.fields.display_timezone'))
                            ->options(fn (): array => InstallWizardTimezoneOptions::optionsForSelect((string) app()->getLocale()))
                            ->searchable()
                            // Filament 可搜索下拉默认只渲染 50 条；时区必须完整列出。
                            ->optionsLimit(count(timezone_identifiers_list()))
                            ->required()
                            ->rules(['timezone'])
                            ->helperText(__('dberp.hints.display_timezone')),
                        Select::make('default_currency_code')
                            ->label(__('dberp.fields.default_currency'))
                            ->options(fn (): array => DberpCurrencySelectOptions::forSelect(
                                $this->data['default_currency_code']
                                    ?? $this->resolveSystemProfileRecord()->default_currency_code,
                            ))
                            ->required()
                            ->rules(['string', 'max:8'])
                            ->helperText(__('dberp.hints.default_currency')),
                        TextInput::make('amount_decimal_places')
                            ->label(__('dberp.fields.amount_decimal_places'))
                            ->numeric()
                            ->minValue(0)
                            ->maxValue(8)
                            ->required(),
                        TextInput::make('quantity_decimal_places')
                            ->label(__('dberp.fields.quantity_decimal_places'))
                            ->numeric()
                            ->minValue(0)
                            ->maxValue(8)
                            ->required(),
                    ])
                    ->columns(2),
            ]);
    }
}
