<?php

namespace App\Components\Client;

use App\Models\Claim\Status;
use App\Models\Client\Client;
use App\Models\LeadSource\LeadSource;
use App\Models\Tranche;
use App\Rules\PhoneNumber;
use App\Services\HistoryService;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Livewire\Component;

class Create extends Component {

    public $title;
    public $first_name;
    public $middle_name;
    public $last_name;
    public $preferred_name;
    public $dob;
    public $email;
    public $phone;
    public $landline;
    public $tranche_id;
    public $lead_source_id;

    protected $messages = [
        'first_name.regex' => 'First name contains invalid characters.',
        'middle_name.regex' => 'Middle name contains invalid characters.',
        'last_name.regex' => 'Last name contains invalid characters.',
        'preferred_name.regex' => 'Preferred name contains invalid characters.',
    ];

    public function render() {
        return view('components.client.create', [
            'tranches' => Tranche::selectRaw("id, CONCAT(funder_name, ' - ', tranche_name) as name")->pluck('name', 'id')->toArray(),
            'lead_sources' => LeadSource::pluck('display_name', 'id')->toArray(),
        ]);
    }

    public function save(HistoryService $service) {
        $this->validate();

        try {
            DB::transaction(function () use ($service) {
                $client = Client::create([
                    'title'          => $this->standardiseName($this->title),
                    'name_first'     => $this->standardiseName($this->first_name),
                    'name_middle'    => $this->standardiseName($this->middle_name),
                    'name_last'      => $this->standardiseName($this->last_name),
                    'name_preferred' => $this->standardiseName($this->preferred_name),
                    'date_of_birth'  => $this->dob ?: null,
                    'email_address'  => $this->email ? strtolower(trim($this->email)) : null,
                    'phone_number'   => $this->phone ? str_replace(' ', '', $this->phone) : null,
                    'landline'       => $this->landline ? str_replace(' ', '', $this->landline) : null,
                    'tranche_id'     => null,
                    'lead_source_id' => $this->lead_source_id ?: null,
                ]);

                $statusId = Status::forType('ha')
                    ->orderBy('sort_order')
                    ->value('id');

                $client->claim()->create([
                    'status_id' => $statusId,
                ]);

                $service->add($client, "New Claim Created.");

                $this->redirectRoute('ha-claims.show', $client);
            });
        } catch (\Exception $exception) {
            Log::error("Failed to create client: " . $exception->getMessage());
            $this->dispatch('toast', message: "Something unexpected occurred, please try again later.", type: 'error');
        }
    }

    protected function standardiseName(?string $value): ?string
    {
        if (!$value) {
            return null;
        }

        $value = trim($value);

        $value = preg_replace('/\s+/', ' ', $value);

        $value = mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');

        return $value;
    }

    protected function rules() {
        return [
            'title'  => ['nullable', 'string', 'max:50', 'regex:/^[a-zA-Z\'\-\s]+$/'],
            'first_name'  => ['required', 'string', 'min:2', 'max:50', 'regex:/^[a-zA-Z\'\-\s]+$/'],
            'middle_name' => ['nullable', 'string', 'min:2', 'max:50', 'regex:/^[a-zA-Z\'\-\s]+$/'],
            'preferred_name' => ['nullable', 'string', 'min:2', 'max:50', 'regex:/^[a-zA-Z\'\-\s]+$/'],
            'last_name'   => ['required', 'string', 'min:2', 'max:50', 'regex:/^[a-zA-Z\'\-\s]+$/'],
            'dob'         => ['nullable', 'date', 'before:-18 years', 'after:-120 years'],
            'email'       => ['nullable', 'email:rfc'],
            'phone'       => ['nullable', new PhoneNumber()],
            'landline'    => ['nullable', new PhoneNumber()],
            'lead_source_id' => ['nullable', 'exists:lead_sources,id'],
        ];
    }
}
