<?php

namespace App\Livewire\Settings;

use App\Domain\Shared\Branding\AppIconGenerator;
use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Shared\Models\Academy;
use App\Domain\Shared\Services\BrandingService;
use App\Domain\Shared\Services\SettingsService;
use Illuminate\Support\Facades\Storage;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Validate;
use App\Domain\Shared\Traits\ChecksTemporaryUploads;
use Livewire\Component;
use Livewire\WithFileUploads;

#[Layout('layouts.app')]
#[Title('إعدادات الهوية البصرية')]
class BrandingSettings extends Component
{
    use WithFileUploads;
    use ChecksTemporaryUploads;

    // Logo uploads
    public $logo;
    public $logo_dark;
    public $favicon;
    public $signature;
    public $login_background;
    public $invoice_header;

    // Current paths
    public ?string $current_logo = null;
    public ?string $current_logo_dark = null;
    public ?string $current_favicon = null;
    public ?string $current_signature = null;
    public ?string $current_login_background = null;
    public ?string $current_invoice_header = null;

    // Colors
    public string $primary_color = '#2563eb';
    public string $secondary_color = '#7c3aed';
    public string $accent_color = '#059669';
    public string $sidebar_bg = '#0f172a';
    public string $sidebar_text = '#e2e8f0';
    public string $sidebar_active = '#2563eb';
    public string $header_bg = '#ffffff';
    public string $success_color = '#10b981';
    public string $warning_color = '#f59e0b';
    public string $danger_color = '#ef4444';

    // Typography
    public string $font_family_ar = 'Cairo';
    public string $font_family_en = 'Inter';
    public string $font_size_base = '14';

    // Invoice/Receipt branding
    public string $invoice_footer_text = '';
    public string $receipt_footer_text = '';
    public string $terms_and_conditions = '';

    // Mobile / PWA identity
    public string $academy_name = '';
    public string $app_short_name = '';
    public string $theme_color = '#2563eb';
    public string $theme_mode = 'light';
    public ?string $current_app_icon = null;
    public ?string $current_splash_image = null;
    public $app_icon;
    public $splash_image;

    // Display options
    public bool $show_logo_in_sidebar = true;
    public bool $show_logo_in_invoice = true;
    public bool $show_signature_in_invoice = false;
    public bool $compact_sidebar = false;

    public function mount(): void
    {
        $this->authorize('settings.manage');

        $settings = app(SettingsService::class);

        $this->current_logo = $settings->get('branding.logo');
        $this->current_logo_dark = $settings->get('branding.logo_dark');
        $this->current_favicon = $settings->get('branding.favicon');
        $this->current_signature = $settings->get('branding.signature');
        $this->current_login_background = $settings->get('branding.login_background');
        $this->current_invoice_header = $settings->get('branding.invoice_header');

        $this->primary_color = $settings->get('branding.primary_color', '#2563eb');
        $this->secondary_color = $settings->get('branding.secondary_color', '#7c3aed');
        $this->accent_color = $settings->get('branding.accent_color', '#059669');
        $this->sidebar_bg = $settings->get('branding.sidebar_bg', '#0f172a');
        $this->sidebar_text = $settings->get('branding.sidebar_text', '#e2e8f0');
        $this->sidebar_active = $settings->get('branding.sidebar_active', '#2563eb');
        $this->header_bg = $settings->get('branding.header_bg', '#ffffff');
        $this->success_color = $settings->get('branding.success_color', '#10b981');
        $this->warning_color = $settings->get('branding.warning_color', '#f59e0b');
        $this->danger_color = $settings->get('branding.danger_color', '#ef4444');

        $this->font_family_ar = $settings->get('branding.font_family_ar', 'Cairo');
        $this->font_family_en = $settings->get('branding.font_family_en', 'Inter');
        $this->font_size_base = $settings->get('branding.font_size_base', '14');

        $this->invoice_footer_text = $settings->get('branding.invoice_footer_text', '');
        $this->receipt_footer_text = $settings->get('branding.receipt_footer_text', '');
        $this->terms_and_conditions = $settings->get('branding.terms_and_conditions', '');

        $this->show_logo_in_sidebar = (bool) $settings->get('branding.show_logo_in_sidebar', true);
        $this->show_logo_in_invoice = (bool) $settings->get('branding.show_logo_in_invoice', true);
        $this->show_signature_in_invoice = (bool) $settings->get('branding.show_signature_in_invoice', false);
        $this->compact_sidebar = (bool) $settings->get('branding.compact_sidebar', false);

        $academy = app('current_academy');
        // branding.academy_name is read by the parent layout and by every
        // printed sheet, and was written by nothing — so both fell back to the
        // literal string "الكابتن" on every tenant.
        $this->academy_name = $settings->get('branding.academy_name') ?: ($academy->name_ar ?: $academy->name);
        $this->app_short_name = $settings->get('branding.app_short_name') ?: $this->academy_name;
        $this->theme_color = $settings->get('branding.theme_color', '#2563eb');
        $this->theme_mode = $settings->get('branding.theme_mode', 'light');
        $this->current_app_icon = $settings->get('branding.app_icon') ?: null;
        $this->current_splash_image = $settings->get('branding.splash_image') ?: null;
    }

    public function updatedLogo(): void
    {
        $this->validate(['logo' => 'image|max:2048|mimes:png,jpg,jpeg,webp']);
    }

    public function updatedLogoDark(): void
    {
        $this->validate(['logo_dark' => 'image|max:2048|mimes:png,jpg,jpeg,webp']);
    }

    public function updatedFavicon(): void
    {
        $this->validate(['favicon' => 'image|max:512|mimes:png,ico']);
    }

    public function updatedSignature(): void
    {
        $this->validate(['signature' => 'image|max:1024|mimes:png,jpg,jpeg']);
    }

    public function updatedLoginBackground(): void
    {
        $this->validate(['login_background' => 'image|max:5120|mimes:png,jpg,jpeg,webp']);
    }

    public function updatedInvoiceHeader(): void
    {
        $this->validate(['invoice_header' => 'image|max:2048|mimes:png,jpg,jpeg']);
    }

    public function removeImage(string $field): void
    {
        $settings = app(SettingsService::class);
        $key = "branding.{$field}";
        $currentPath = $settings->get($key);

        if ($currentPath && Storage::disk('public')->exists($currentPath)) {
            Storage::disk('public')->delete($currentPath);
        }

        $settings->set($key, null, 'branding', 'string');
        $this->{"current_{$field}"} = null;

        app(BrandingService::class)->bump(app('current_academy')->id);
    }

    public function save(): void
    {
        $this->validate([
            'logo' => 'nullable|image|max:2048|mimes:png,jpg,jpeg,webp',
            'logo_dark' => 'nullable|image|max:2048|mimes:png,jpg,jpeg,webp',
            'favicon' => 'nullable|image|max:512|mimes:png,ico',
            'signature' => 'nullable|image|max:1024|mimes:png,jpg,jpeg',
            'login_background' => 'nullable|image|max:5120|mimes:png,jpg,jpeg,webp',
            'invoice_header' => 'nullable|image|max:2048|mimes:png,jpg,jpeg',
            'app_icon' => 'nullable|image|max:2048|mimes:png,jpg,jpeg',
            'splash_image' => 'nullable|image|max:4096|mimes:png,jpg,jpeg',
            'academy_name' => 'required|string|max:120',
            'app_short_name' => 'required|string|max:24',
            'theme_color' => 'required|regex:/^#[0-9a-fA-F]{6}$/',
            'theme_mode' => 'required|in:light,dark,auto',
            'primary_color' => 'required|regex:/^#[0-9a-fA-F]{6}$/',
            'secondary_color' => 'required|regex:/^#[0-9a-fA-F]{6}$/',
            'accent_color' => 'required|regex:/^#[0-9a-fA-F]{6}$/',
            'sidebar_bg' => 'required|regex:/^#[0-9a-fA-F]{6}$/',
            'sidebar_text' => 'required|regex:/^#[0-9a-fA-F]{6}$/',
            'sidebar_active' => 'required|regex:/^#[0-9a-fA-F]{6}$/',
            'header_bg' => 'required|regex:/^#[0-9a-fA-F]{6}$/',
            'font_size_base' => 'required|integer|min:12|max:18',
        ]);

        $settings = app(SettingsService::class);
        $academy = app('current_academy');
        $basePath = "branding/{$academy->id}";

        $uploads = [
            'logo' => $this->logo,
            'logo_dark' => $this->logo_dark,
            'favicon' => $this->favicon,
            'signature' => $this->signature,
            'login_background' => $this->login_background,
            'invoice_header' => $this->invoice_header,
            'app_icon' => $this->app_icon,
            'splash_image' => $this->splash_image,
        ];

        foreach ($uploads as $field => $file) {
            if ($file) {
                // The tmp file can be gone by the time Save is pressed — a
                // redeploy between picking the logo and saving is enough. Ask
                // for it again instead of throwing a Flysystem error.
                if (! $this->temporaryUploadIsUsable($field, $file)) {
                    continue;
                }

                $oldPath = $settings->get("branding.{$field}");
                if ($oldPath && Storage::disk('public')->exists($oldPath)) {
                    Storage::disk('public')->delete($oldPath);
                }

                $path = $file->store("{$basePath}/{$field}", 'public');
                $settings->set("branding.{$field}", $path, 'branding', 'string');
                $this->{"current_{$field}"} = $path;
                $this->{$field} = null;
            }
        }

        $colorSettings = [
            'primary_color', 'secondary_color', 'accent_color',
            'sidebar_bg', 'sidebar_text', 'sidebar_active', 'header_bg',
            'success_color', 'warning_color', 'danger_color',
        ];

        foreach ($colorSettings as $key) {
            $settings->set("branding.{$key}", $this->{$key}, 'branding', 'string');
        }

        $settings->set('branding.font_family_ar', $this->font_family_ar, 'branding', 'string');
        $settings->set('branding.font_family_en', $this->font_family_en, 'branding', 'string');
        $settings->set('branding.font_size_base', $this->font_size_base, 'branding', 'integer');

        $settings->set('branding.invoice_footer_text', $this->invoice_footer_text, 'branding', 'string');
        $settings->set('branding.receipt_footer_text', $this->receipt_footer_text, 'branding', 'string');
        $settings->set('branding.terms_and_conditions', $this->terms_and_conditions, 'branding', 'string');

        $settings->set('branding.academy_name', $this->academy_name, 'branding', 'string');
        $settings->set('branding.app_short_name', $this->app_short_name, 'branding', 'string');
        $settings->set('branding.theme_color', $this->theme_color, 'branding', 'string');
        $settings->set('branding.theme_mode', $this->theme_mode, 'branding', 'string');

        $settings->set('branding.show_logo_in_sidebar', $this->show_logo_in_sidebar ? '1' : '0', 'branding', 'boolean');
        $settings->set('branding.show_logo_in_invoice', $this->show_logo_in_invoice ? '1' : '0', 'branding', 'boolean');
        $settings->set('branding.show_signature_in_invoice', $this->show_signature_in_invoice ? '1' : '0', 'branding', 'boolean');
        $settings->set('branding.compact_sidebar', $this->compact_sidebar ? '1' : '0', 'branding', 'boolean');

        if ($this->current_logo) {
            $academy->update(['logo_path' => $this->current_logo]);
        }

        // Regenerate the square icon set the PWA manifest and the native shell
        // read. Content-hashed filenames, because nginx serves assets with
        // `expires 1y; immutable` — a stable name would pin a rebranded icon on
        // every installed device for a year.
        $iconSource = $this->current_app_icon ?: $this->current_logo;

        if ($iconSource) {
            try {
                $icons = app(AppIconGenerator::class)->generate($academy->id, $iconSource, '#ffffff');
                $settings->set('branding.icon_set', json_encode($icons), 'branding', 'json');
            } catch (DomainException $e) {
                // A bad logo must not block a colour change.
                session()->flash('error', $e->getMessage());
            }
        }

        // Everything above is cached under the academy's branding_version, so
        // nothing changes anywhere until the version moves.
        app(BrandingService::class)->bump($academy->id);

        session()->flash('success', __('تم حفظ إعدادات الهوية البصرية بنجاح'));
    }

    public function render()
    {
        return view('livewire.settings.branding-settings');
    }
}
