<?php

declare(strict_types=1);

namespace Database\Seeders;

use App\Models\Setting;
use App\Services\AppSettings;
use App\Services\ImportService;
use Illuminate\Database\Seeder;

/**
 * Declares every application setting.
 *
 * This seeder is idempotent and is safe — expected, in fact — to re-run on
 * every deploy: it creates keys that are missing and refreshes the presentation
 * metadata (label, description, group, type) of keys that already exist,
 * without ever overwriting a value a master user has chosen.
 *
 * Adding a setting to the application means adding it here. Nothing else
 * creates rows in this table.
 */
class SettingSeeder extends Seeder
{
    public function run(): void
    {
        foreach ($this->definitions() as $definition) {
            $setting = Setting::query()->firstOrNew(['key' => $definition['key']]);

            // Presentation metadata always tracks the code.
            $setting->fill([
                'group' => $definition['group'],
                'type' => $definition['type'],
                'label' => $definition['label'],
                'description' => $definition['description'],
                'is_editable' => $definition['is_editable'] ?? true,
            ]);

            // The value is only ever seeded on first creation.
            if (! $setting->exists) {
                $setting->value = $definition['value'];
            }

            $setting->save();
        }

        app(AppSettings::class)->flush();
    }

    /**
     * @return array<int, array{
     *     key: string,
     *     group: string,
     *     type: string,
     *     value: string|null,
     *     label: string,
     *     description: string|null,
     *     is_editable?: bool
     * }>
     */
    private function definitions(): array
    {
        return [
            // ---------------------------------------------------------- company
            [
                'key' => 'company_name',
                'group' => 'company',
                'type' => Setting::TYPE_STRING,
                'value' => 'Aumni Techworks LLP',
                'label' => 'Company Name',
                'description' => 'Shown in the sidebar, on printed reports and in email footers.',
            ],
            [
                'key' => 'company_logo',
                'group' => 'company',
                'type' => Setting::TYPE_FILE,
                'value' => null,
                'label' => 'Company Logo',
                'description' => 'Displayed in the sidebar in place of the default mark. PNG, JPG or SVG, up to 2 MB.',
            ],
            [
                'key' => 'company_address',
                'group' => 'company',
                'type' => Setting::TYPE_STRING,
                'value' => null,
                'label' => 'Company Address',
                'description' => 'Printed on exported reports. Multiple lines are shown as written.',
            ],
            [
                'key' => 'contact_email',
                'group' => 'company',
                'type' => Setting::TYPE_STRING,
                'value' => null,
                'label' => 'Contact Email',
                'description' => 'The address staff should use for asset-management queries.',
            ],
            [
                'key' => 'contact_phone',
                'group' => 'company',
                'type' => Setting::TYPE_STRING,
                'value' => null,
                'label' => 'Contact Phone',
                'description' => 'Shown alongside the contact email wherever the two are printed together.',
            ],

            // ---------------------------------------------------------- general
            [
                'key' => 'application_name',
                'group' => 'general',
                'type' => Setting::TYPE_STRING,
                'value' => 'Aumni AMS',
                'label' => 'Application Name',
                'description' => 'Shown in the browser title bar and the topbar.',
            ],
            [
                'key' => 'date_format',
                'group' => 'general',
                'type' => Setting::TYPE_STRING,
                'value' => 'd M Y',
                'label' => 'Date Format',
                'description' => 'PHP date format used for every date displayed in the interface.',
            ],
            [
                'key' => 'datetime_format',
                'group' => 'general',
                'type' => Setting::TYPE_STRING,
                'value' => 'd M Y, H:i',
                'label' => 'Date & Time Format',
                'description' => 'PHP date format used wherever a time of day is shown.',
            ],
            [
                'key' => 'timezone',
                'group' => 'general',
                'type' => Setting::TYPE_STRING,
                'value' => 'Asia/Kolkata',
                'label' => 'Timezone',
                'description' => 'Applied at the start of every request, so it governs every "now" the application computes from that point on — it does not reinterpret timestamps already stored.',
            ],
            [
                'key' => 'default_currency',
                'group' => 'general',
                'type' => Setting::TYPE_STRING,
                'value' => 'INR',
                'label' => 'Currency',
                'description' => 'ISO currency code applied to new asset purchase costs.',
            ],
            [
                'key' => 'pagination_per_page',
                'group' => 'general',
                'type' => Setting::TYPE_INTEGER,
                'value' => '25',
                'label' => 'Rows Per Page',
                'description' => 'Number of records shown per page in every listing.',
            ],

            // ----------------------------------------------------------- assets
            [
                'key' => 'asset_tag_prefix',
                'group' => 'assets',
                'type' => Setting::TYPE_STRING,
                'value' => 'AUM',
                'label' => 'Asset Tag Prefix',
                'description' => 'Leading segment of every generated asset tag, e.g. AUM-LAP-0042.',
            ],
            [
                'key' => 'asset_tag_scope',
                'group' => 'assets',
                'type' => Setting::TYPE_STRING,
                'value' => 'per_category',
                'label' => 'Asset Tag Numbering',
                'description' => 'Whether the sequence restarts per category (AUM-LAP-0001) or runs globally (AUM-0001).',
            ],
            [
                'key' => 'asset_tag_sequence_padding',
                'group' => 'assets',
                'type' => Setting::TYPE_INTEGER,
                'value' => '4',
                'label' => 'Asset Tag Number Length',
                'description' => 'How many digits the sequence is padded to.',
            ],
            [
                'key' => 'import_max_rows',
                'group' => 'assets',
                'type' => Setting::TYPE_INTEGER,
                'value' => (string) ImportService::MAX_ROWS,
                'label' => 'Import Row Cap',
                'description' => 'Maximum data rows accepted in a single bulk-import file. Imports run synchronously inside the request, so a very high cap risks a timeout on shared hosting.',
            ],

            // ---------------------------------------------------- notifications
            [
                'key' => 'warranty_alert_days',
                'group' => 'notifications',
                'type' => Setting::TYPE_JSON,
                'value' => '[30,15,7]',
                'label' => 'Warranty Alert Windows',
                'description' => 'Days before expiry at which a warranty appears in the daily digest.',
            ],
            [
                'key' => 'warranty_alert_recipients',
                'group' => 'notifications',
                'type' => Setting::TYPE_JSON,
                'value' => '[]',
                'label' => 'Warranty Alert Recipients',
                'description' => 'Email addresses that receive the daily warranty expiry digest.',
            ],
            [
                'key' => 'enable_warranty_emails',
                'group' => 'notifications',
                'type' => Setting::TYPE_BOOLEAN,
                'value' => '0',
                'label' => 'Send Warranty Emails',
                'description' => 'Turn the daily warranty expiry digest on or off.',
            ],
            [
                'key' => 'mail_from_name',
                'group' => 'notifications',
                'type' => Setting::TYPE_STRING,
                'value' => null,
                'label' => 'Email From Name',
                'description' => 'Sender name on the warranty digest. Falls back to the application name when blank.',
            ],
            [
                'key' => 'mail_from_address',
                'group' => 'notifications',
                'type' => Setting::TYPE_STRING,
                'value' => null,
                'label' => 'Email From Address',
                'description' => 'Sender address on the warranty digest. Falls back to the configured server default when blank — changing it does not change how mail is actually routed, only the From header.',
            ],

            // --------------------------------------------------------- security
            [
                'key' => 'password_min_length',
                'group' => 'security',
                'type' => Setting::TYPE_INTEGER,
                'value' => '10',
                'label' => 'Minimum Password Length',
                'description' => 'Minimum characters for a new password. Cannot be set below the configured floor of 10.',
            ],
            [
                'key' => 'audit_retention_months',
                'group' => 'security',
                'type' => Setting::TYPE_INTEGER,
                'value' => '24',
                'label' => 'Audit Log Retention (months)',
                'description' => 'Routine audit entries older than this are pruned weekly. Asset custody events (assigned/returned/renewed) are kept permanently regardless of this setting.',
            ],
        ];
    }
}
