<?php

namespace App\Components\Claim;

use App\Models\Claim\Status;
use App\Models\Client\PreviousName;
use App\Services\HistoryService;
use Livewire\Component;

class StatusController extends Component {

    public ?string $new_status_name = '';
    public ?string $new_status_description = '';
    public ?string $new_status_color = '';

    public bool $show = false;

    public bool $editing = false;
    public $status;
    private array $rules = [
        'new_status_name' => 'required|string|max:255',
        'new_status_description' => 'required|string|max:255',
        'new_status_color' => 'required|string|max:255|regex:/^#(?:[0-9a-fA-F]{3}){1,2}$/',
    ];

    public function mount(): void {
        $this->authorize('statuses.view');
    }

    public function showAdd() {
        $this->show = true;
    }

    public function hideAdd() {
        $this->reset('new_status_name', 'new_status_description', 'new_status_color');
        $this->show = false;
    }

    public function loadEdit(int $id) {
        $status = Status::find($id);

        $this->status = $status;
        $this->new_status_name = $status->display_name;
        $this->new_status_description = $status->description;
        $this->new_status_color = $status->colour;
        $this->editing = true;

        $this->showAdd();
    }

    public function editStatus(HistoryService $service) {
        $this->authorize('statuses.edit');

        $before = $this->status->only(['display_name', 'description', 'colour']);

        $this->status->update([
            'display_name' => $this->new_status_name,
            'description' => $this->new_status_description,
            'colour' => $this->new_status_color,
        ]);

        $changed = [];
        foreach ($this->status->getChanges() as $field => $newValue) {
            if (in_array($field, ['updated_at', 'created_at'])) {
                continue;
            }
            $changed[$field] = ['from' => $before[$field] ?? null, 'to' => $newValue];
        }

        $service->addForActor("Edited status '{$this->status->display_name}'", [
            'status_id' => $this->status->id,
            'changed'   => $changed,
        ]);

        $this->hideAdd();
    }

    public function updateOrder(HistoryService $historyService, $orderedIds) {
        $this->authorize('statuses.edit');
        $before = Status::orderBy('sort_order')
            ->get(['id', 'sort_order'])
            ->pluck('sort_order', 'id')
            ->toArray();

        foreach ($orderedIds as $index => $id) {
            Status::where('id', $id)->update([
                'sort_order' => $index,
            ]);
        }

        $after = Status::orderBy('sort_order')
            ->get(['id', 'sort_order'])
            ->pluck('sort_order', 'id')
            ->toArray();

        $historyService->add(
            auth()->user(),
            "Modified status order.",
            [
                'before' => $before,
                'after'  => $after,
            ]
        );
    }


    public function placeholder() {
        return <<<'HTML'
        <div class="row">
            <div class="col-12">
                <div class="card">
                    <div class="card-body">
                        <div class="placeholder placeholder-wave w-100"></div>
                        <div class="placeholder placeholder-wave w-100"></div>
                        <div class="placeholder placeholder-wave w-75"></div>
                        <div class="placeholder placeholder-wave w-50"></div>
                    </div>
                </div>
            </div>
        </div>
        HTML;
    }

    public function deleteStatus(HistoryService $service, int $id) {
        $this->authorize('statuses.delete');
        $status = Status::findOrFail($id);

        if ($status->hasClaims()) {
            $this->dispatch('toast', message: 'Cannot delete: this status is attached to one or more claims.', type: 'danger');
            return;
        }

        $context = [
            'status_id'  => $status->id,
            'name'       => $status->display_name,
            'colour'     => $status->colour,
            'type'       => $status->type,
        ];

        $status->delete();
        $service->addForActor("Deleted status '{$context['name']}'", $context);
    }

    public function addStatus(HistoryService $service) {
        $this->authorize('statuses.create');
        $data = $this->validate($this->rules);

        try {
            $status = new Status([
                'display_name' => $data['new_status_name'],
                'description' => $data['new_status_description'],
                'colour' => $data['new_status_color'],
                'type' => 'ha',
            ]);

            $status->save();

            $service->addForActor("Created status '{$data['new_status_name']}'", [
                'status_id'   => $status->id,
                'name'        => $status->display_name,
                'description' => $status->description,
                'type'        => $status->type,
            ]);

            $this->hideAdd();
        } catch (\Throwable $th) {}
    }

    public function render() {
        return view('components.claim.status-controller', [
            'statuses' => Status::forType('ha')->withCount('claims')->orderBy('sort_order')->get(),
        ]);
    }
}
