<?php

namespace App\Livewire\Pages\Bio;

use App\Domains\Bio\Models\BioBlock;
use App\Domains\Bio\Models\BioPage;
use Illuminate\View\View;
use Livewire\Attributes\Renderless;
use Livewire\Component;

class Edit extends Component
{
    public int $pageId = 0;

    public string $workspaceUlid = '';

    public string $publicUrlBase = '';

    public string $displayUrlBase = '';

    public function mount(string $bioUlid): void
    {
        $workspace = require_workspace();

        $page = BioPage::where('ulid', $bioUlid)
            ->where('workspace_id', $workspace->id)
            ->firstOrFail();

        $this->pageId = $page->id;
        $this->workspaceUlid = $workspace->ulid;

        $apex = config('services.hetzner.zone', 'nimu.li');

        if (! $workspace->isFreePlan() && $workspace->subdomain_full) {
            $this->publicUrlBase  = "https://{$workspace->subdomain_full}/b";
            $this->displayUrlBase = "{$workspace->subdomain_full}/b";
        } else {
            $this->publicUrlBase  = "https://{$apex}/b/{$workspace->slug}";
            $this->displayUrlBase = "{$apex}/b/{$workspace->slug}";
        }
    }

    public function save(array $state): void
    {
        $page = BioPage::findOrFail($this->pageId);

        $newSlug = $state['slug'] ?? $page->slug;

        $slugTaken = BioPage::where('workspace_id', $page->workspace_id)
            ->where('slug', $newSlug)
            ->where('id', '!=', $page->id)
            ->whereNull('deleted_at')
            ->exists();

        if ($slugTaken) {
            $this->dispatch('toast', message: 'Slug "' . $newSlug . '" ist bereits vergeben.', type: 'error');

            return;
        }

        if (! preg_match('/^[a-zA-Z0-9_-]{1,64}$/', $newSlug)) {
            $this->dispatch('toast', message: 'Slug: nur Buchstaben, Zahlen, - und _. Max 64 Zeichen.', type: 'error');

            return;
        }

        $displayName = $state['profile']['displayName'] ?? '';

        $page->update([
            'slug'         => $newSlug,
            'title'        => ['en' => $displayName, 'de' => $displayName],
            'is_published' => false,
            'theme'        => [
                'profile' => $state['profile'] ?? [],
                'theme'   => $state['theme']   ?? [],
                'socials' => $state['socials'] ?? [],
            ],
        ]);

        BioBlock::where('bio_page_id', $this->pageId)->delete();

        foreach ($state['blocks'] ?? [] as $i => $block) {
            BioBlock::create([
                'bio_page_id' => $this->pageId,
                'position'    => $i,
                'type'        => $block['type'] ?? 'link',
                'config'      => array_diff_key($block, array_flip(['id', 'type', '_collapsed'])),
            ]);
        }

        $this->dispatch('toast', message: 'Gespeichert', type: 'success');
    }

    #[Renderless]
    public function checkSlug(string $slug): bool
    {
        $page = BioPage::findOrFail($this->pageId);

        return BioPage::where('workspace_id', $page->workspace_id)
            ->where('slug', $slug)
            ->where('id', '!=', $page->id)
            ->whereNull('deleted_at')
            ->exists();
    }

    public function publish(array $state): void
    {
        $this->save($state);

        BioPage::where('id', $this->pageId)->update(['is_published' => true]);

        $this->dispatch('toast', message: 'Veröffentlicht', type: 'success');
    }

    public function unpublish(): void
    {
        BioPage::where('id', $this->pageId)->update(['is_published' => false]);

        $this->dispatch('toast', message: 'Als Entwurf gespeichert', type: 'success');
    }

    public function render(): View
    {
        $page = BioPage::with('blocks')->findOrFail($this->pageId);

        $theme = is_array($page->theme) ? $page->theme : [];

        $initialState = [
            'uid'         => $page->blocks->count() + 100,
            'slug'        => $page->slug,
            'isPublished' => $page->is_published,
            'profile'     => $theme['profile'] ?? [
                'avatar'      => null,
                'displayName' => $page->getTranslation('title', 'en'),
                'handle'      => $page->slug,
                'bio'         => '',
                'verified'    => false,
            ],
            'theme' => array_merge([
                'bgType'      => 'gradient',
                'bg1'         => '#0f0a2e',
                'bg2'         => '#6b1b9a',
                'bgImage'     => null,
                'dark'        => true,
                'button'      => 'rounded',
                'font'        => 'geist',
                'borderColor' => '#7c3aed',
                'shadowColor' => '#18181b',
            ], $theme['theme'] ?? []),
            'socials' => $theme['socials'] ?? [],
            'blocks'  => $page->blocks
                ->sortBy('position')
                ->map(fn ($b) => array_merge(
                    ['id' => $b->id, 'type' => $b->type],
                    $b->config ?? []
                ))
                ->values()
                ->toArray(),
        ];

        return view('livewire.pages.bio.edit', [
            'page'           => $page,
            'workspaceUlid'  => $this->workspaceUlid,
            'bioUlid'        => $page->ulid,
            'initialState'   => $initialState,
            'publicUrlBase'  => $this->publicUrlBase,
            'displayUrlBase' => $this->displayUrlBase,
        ])->layout('layouts.nimuli-app', ['title' => 'Bio Editor']);
    }
}
