<?php

namespace App\Livewire\Admin;

use App\Models\Datacenter;
use Illuminate\Validation\Rule;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Validate;
use Livewire\Component;

#[Layout('layouts.admin')]
class Datacenters extends Component
{
    #[Validate(['required', 'string', 'max:8', 'regex:/^[a-z0-9]([a-z0-9-]{0,6}[a-z0-9])?$/', 'unique:datacenters,code'])]
    public string $code = '';

    #[Validate('required|string|max:255')]
    public string $name = '';

    /**
     * Which building, not which city — fsn-dc-15. Optional, free text, and
     * nothing keys off it: see EditDatacenter and the migration that adds it.
     *
     * Offered here as well as in the edit modal so that creating a datacenter
     * and saying which one it is are not two separate errands.
     */
    #[Validate('nullable|string|max:255')]
    public string $facility = '';

    // Country picked from config/countries.php (no manual code typos).
    #[Validate('nullable|string|max:2')]
    public string $location = '';

    public function save(): void
    {
        $this->authorize('datacenters.manage');
        // Normalize before validating so the unique check matches how the row is
        // stored — otherwise `FSN` passes the rule but the lowercased insert collides.
        $this->code = strtolower(trim($this->code));

        // Country must be one of the curated list — a forged request can bypass
        // the <select>, so enforce membership server-side (mirrors EditDatacenter).
        $data = $this->validate([
            // A datacenter code becomes a DNS label (fsn-01.node.clupilot.com),
            // so it has to be one: lowercase, no underscores, no leading or
            // trailing dash.
            'code' => ['required', 'string', 'max:8', 'regex:/^[a-z0-9]([a-z0-9-]{0,6}[a-z0-9])?$/', 'unique:datacenters,code'],
            'name' => 'required|string|max:255',
            'facility' => 'nullable|string|max:255',
            'location' => ['nullable', Rule::in(array_keys((array) config('countries')))],
        ]);

        Datacenter::create([
            'code' => $data['code'],
            'name' => $data['name'],
            'facility' => $data['facility'] ?: null,
            'location' => $data['location'] ?: null,
            'active' => true,
        ]);

        $this->reset('code', 'name', 'facility', 'location');
        $this->dispatch('notify', message: __('datacenters.created'));
    }

    public function toggle(string $uuid): void
    {
        $this->authorize('datacenters.manage');
        $datacenter = Datacenter::query()->where('uuid', $uuid)->first();
        $datacenter?->update(['active' => ! $datacenter->active]);
    }

    public function render()
    {
        return view('livewire.admin.datacenters', [
            'datacenters' => Datacenter::query()->withCount('hosts')->orderBy('name')->get(),
            'countries' => config('countries'),
        ]);
    }
}
