<?php

namespace App\Livewire\Pages\QrCodes;

use App\Domains\QrCode\Models\QrCode;
use Illuminate\View\View;
use Livewire\Component;

class Create extends Component
{
    public string $workspaceUlid = '';

    public string $type = 'url';

    public string $label = '';

    // URL / generic
    public string $url = '';

    // vCard
    public string $vcardName = '';

    public string $vcardPhone = '';

    public string $vcardEmail = '';

    public string $vcardCompany = '';

    public string $vcardWebsite = '';

    // WiFi
    public string $wifiSsid = '';

    public string $wifiPassword = '';

    public string $wifiEncryption = 'WPA';

    public bool $wifiHidden = false;

    // Email
    public string $emailTo = '';

    public string $emailSubject = '';

    public string $emailBody = '';

    // SMS
    public string $smsTo = '';

    public string $smsBody = '';

    // Text
    public string $textContent = '';

    // Style
    public string $fgColor = '#1a0b3d';

    public string $bgColor = '#ffffff';

    public string $logoUrl = '';

    public string $dotStyle = 'square';

    public string $cornerSquare = 'extra-rounded';

    public string $cornerDot = 'dot';

    public int $size = 1024;

    public int $margin = 10;

    public string $errorCorrection = 'Q';

    // Gradient
    public bool $gradientEnabled = false;

    public string $gradStart = '#8b5cf6';

    public string $gradEnd = '#ec4899';

    // Logo options
    public int $logoSize = 35;

    public int $logoMargin = 6;

    public bool $hideDots = true;

    // Frame
    public string $frame = 'none';

    public string $frameText = '';

    public string $frameColor = '#7c3aed';

    // Advanced
    public bool $isDynamic = true;

    public ?int $scanLimit = null;

    public string $expiresAt = '';

    public function mount(): void
    {
        $this->workspaceUlid = require_workspace()->ulid;
    }

    public function updated(string $prop): void
    {
        $this->dispatch('qr-preview-update',
            payload: $this->buildPayload(),
            style: [
                'fg'             => $this->fgColor,
                'bg'             => $this->bgColor,
                'dotStyle'       => $this->dotStyle,
                'cornerSquare'   => $this->cornerSquare,
                'cornerDot'      => $this->cornerDot,
                'margin'         => $this->margin,
                'ec'             => $this->errorCorrection,
                'logoUrl'        => $this->logoUrl ?: null,
                'useGradient'    => $this->gradientEnabled,
                'gradStart'      => $this->gradStart,
                'gradEnd'        => $this->gradEnd,
                'logoSize'       => $this->logoSize / 100,
                'logoMargin'     => $this->logoMargin,
                'hideDots'       => $this->hideDots,
            ]
        );
    }

    public function buildPayload(): string
    {
        return match ($this->type) {
            'email'  => 'mailto:'.trim($this->emailTo).'?subject='.urlencode($this->emailSubject).'&body='.urlencode($this->emailBody),
            'phone'  => 'tel:'.trim($this->url),
            'sms'    => 'SMSTO:'.trim($this->smsTo).':'.$this->smsBody,
            'vcard'  => $this->buildVcard(),
            'wifi'   => $this->buildWifi(),
            'text'   => $this->textContent,
            default  => $this->normalizeUrl(trim($this->url)),
        };
    }

    private function buildVcard(): string
    {
        return implode("\n", array_filter([
            'BEGIN:VCARD',
            'VERSION:3.0',
            $this->vcardName ? "FN:{$this->vcardName}" : null,
            $this->vcardPhone ? "TEL:{$this->vcardPhone}" : null,
            $this->vcardEmail ? "EMAIL:{$this->vcardEmail}" : null,
            $this->vcardCompany ? "ORG:{$this->vcardCompany}" : null,
            $this->vcardWebsite ? "URL:{$this->vcardWebsite}" : null,
            'END:VCARD',
        ]));
    }

    private function buildWifi(): string
    {
        $enc = $this->wifiEncryption ?: 'nopass';
        $hidden = $this->wifiHidden ? 'true' : 'false';

        return "WIFI:T:{$enc};S:{$this->wifiSsid};P:{$this->wifiPassword};H:{$hidden};;";
    }

    private function normalizeUrl(string $url): string
    {
        if ($url && !preg_match('/^https?:\/\//i', $url)) {
            return 'https://' . $url;
        }

        return $url;
    }

    public function save(): void
    {
        $urlRule = match ($this->type) {
            'url'   => 'required|url|max:2048',
            'phone' => 'required|max:50',
            'email' => 'nullable',
            default => 'nullable',
        };

        $this->validate([
            'type'           => 'required|in:url,vcard,wifi,text,email,phone,sms',
            'label'          => 'nullable|max:200',
            'url'            => $urlRule,
            'emailTo'        => $this->type === 'email' ? 'required|email|max:200' : 'nullable',
            'smsTo'          => $this->type === 'sms' ? 'required|max:50' : 'nullable',
            'vcardName'      => $this->type === 'vcard' ? 'required|max:200' : 'nullable',
            'wifiSsid'       => $this->type === 'wifi' ? 'required|max:200' : 'nullable',
            'fgColor'        => ['required', 'regex:/^#[0-9a-fA-F]{6}$/'],
            'bgColor'        => ['required', 'regex:/^#[0-9a-fA-F]{6}$/'],
            'logoUrl'        => 'nullable|url|max:2048',
            'errorCorrection' => 'in:L,M,Q,H',
            'frame'          => 'in:none,label-bottom,label-top',
            'gradStart'      => ['nullable', 'regex:/^#[0-9a-fA-F]{6}$/'],
            'gradEnd'        => ['nullable', 'regex:/^#[0-9a-fA-F]{6}$/'],
        ]);

        $workspace = Workspace::where('ulid', $this->workspaceUlid)->firstOrFail();

        $dbType = match ($this->type) {
            'email', 'phone', 'sms' => 'url',
            default => $this->type,
        };

        QrCode::create([
            'workspace_id' => $workspace->id,
            'type'         => $dbType,
            'payload'      => [
                'data'         => $this->buildPayload(),
                'label'        => $this->label ?: null,
                'display_type' => $this->type,
            ],
            'style'        => [
                'fg_color'         => $this->fgColor,
                'bg_color'         => $this->bgColor,
                'logo_url'         => $this->logoUrl ?: null,
                'dot_style'        => $this->dotStyle,
                'corner_square'    => $this->cornerSquare,
                'corner_dot'       => $this->cornerDot,
                'size'             => $this->size,
                'margin'           => $this->margin,
                'error_correction' => $this->errorCorrection,
                'gradient_enabled' => $this->gradientEnabled,
                'grad_start'       => $this->gradStart,
                'grad_end'         => $this->gradEnd,
                'logo_size'        => $this->logoSize,
                'logo_margin'      => $this->logoMargin,
                'hide_dots'        => $this->hideDots,
                'frame'            => $this->frame,
                'frame_text'       => $this->frameText ?: null,
                'frame_color'      => $this->frameColor,
            ],
            'is_dynamic'   => $this->isDynamic,
            'scan_limit'   => $this->scanLimit ?: null,
            'expires_at'   => $this->expiresAt ?: null,
        ]);

        $this->dispatch('toast', message: 'QR-Code erstellt', type: 'success');
        $this->redirect(route('w.qr.index', $workspace->ulid), navigate: true);
    }

    public function render(): View
    {
        return view('livewire.pages.qr-codes.create')
            ->layout('layouts.nimuli-app', ['title' => 'QR Code erstellen']);
    }
}
