<?php

namespace App\Components\Client;

use App\Models\Claim\CareSetting;
use App\Models\Claim\Status;
use App\Models\Client\Client;
use App\Models\Institution\Institution;
use App\Models\LeadSource\LeadSource;
use App\Models\LeadSource\LeadSourceEndpoint;
use App\Models\Tag;
use App\Models\Tranche;
use App\Models\User\User;
use App\Services\ClientService;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Attributes\Lazy;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

#[Lazy]
class Index extends Component {

    use WithPagination, AuthorizesRequests;

    public $search = '';
    public $sortColumn = 'name_last';
    public $sortDirection = 'asc';
    public $perPage = 10;

    #[Url(history: true)]
    public $status_id = null;
    #[Url(history: true)]
    public $lead_source_id = null;
    #[Url(history: true)]
    public $url = null;
    #[Url(history: true)]
    public $date_from = null;
    #[Url(history: true)]
    public $date_to = null;
    #[Url(history: true)]
    public $care_setting_id = null;
    #[Url(history: true)]
    public $tranche_id = null;
    protected ClientService $clientService;
    #[Url(history: true)]
    public $priority;
    #[Url(history: true)]
    public $tag_id;
    #[Url(history: true)]
    public $handler = null;

    public function placeholder() {
        return <<<'HTML'
        <div class="row">
            <div class="col-12 col-md-9">
                <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 boot(ClientService $clientService) {
        $this->clientService = $clientService;
    }


    public function render() {
        $clients = Client::query();

        if ($this->search !== '') {
            $search = trim($this->search);

            if (str_starts_with($search, '07')) {
                $search = '+44' . substr($search, 1);
            }

            $clients
                ->where(function($query) use ($search) {
                    $query
                        ->where('name_first', 'like', '%' . $search . '%')
                        ->orWhere('email_address', 'like', '%' . $search . '%')
                        ->orWhereRaw("CONCAT(name_first, ' ', name_last) LIKE ?", ["%{$search}%"])
                        ->orWhere('phone_number', 'like', '%' . $search . '%')
                        ->orWhere('name_last', 'like', '%' . $search . '%');
                });

            if(is_numeric($this->search)) {
                $clients->orWhere('id', $search - 100000);
            }
        }

        if ($this->status_id) {
            $clients->whereHas('claim', function($claims) {
                $claims->where('status_id', $this->status_id);
            });
        }

        if(is_numeric($this->tranche_id)) {
            $tranche = $this->tranche_id ?: null;
            $clients->where('tranche_id', $tranche);
        }

        if ($this->lead_source_id !== null) {
            if($this->lead_source_id) {
                $clients->where('lead_source_id', $this->lead_source_id);
            } else {
                $clients->whereNull('lead_source_id');
            }
        }

        if ($this->url !== null) {
            if($this->url) {
                $clients->where('lead_source_endpoint_id', $this->url);
            } else {
                $clients->whereNull('lead_source_endpoint_id');
            }
        }

        if ($this->tag_id) {
            $clients->whereHas('claim.tags', function ($tags) {
                $tags->where('tags.id', $this->tag_id);
            });
        }

        if ($this->priority) {
            $clients->where(function ($priorityQuery) {
                if ($this->priority == 1) {
                    $priorityQuery->whereHas('claim.terminalIllness')
                        ->orWhereDate('clients.date_of_birth', '<', now()->subYears(68));
                } elseif ($this->priority == 2) {
                    $priorityQuery->whereHas('claim', function ($claim) {
                        $claim->whereDoesntHave('terminalIllness');
                    })->whereDate('clients.date_of_birth', '>', now()->subYears(68));
                }
            });
        }

        if($this->date_from) {
            $clients->whereDate('created_at', '>=', $this->date_from);
        }

        if($this->date_to) {
            $clients->whereDate('created_at', '<=', $this->date_to);
        }

        if($this->handler) {
            $handler = $this->handler;
            $clients->whereHas('handlers', function ($query) use ($handler) {
                $query->where('user_id', $handler);
            });
        }

        if($this->care_setting_id) {
            $clients->whereHas('claim', function($claim) {
                $claim->whereHas('careSettings', function($careSettings) {
                    $careSettings->where('institution_id', $this->care_setting_id);
                });
            });
        }

        $clients = $clients
            ->with(['claim.status', 'claim.terminalIllness', 'tranche'])
            ->paginate($this->perPage);

        $endpoints = LeadSourceEndpoint::query()
            ->get(['id', 'url', 'display_name'])
            ->mapWithKeys(fn ($endpoint) => [
                $endpoint->id => "{$endpoint->url} - {$endpoint->display_name}"
            ])
            ->toArray();

        $tranches = Tranche::query()->get([
            'funder_name', 'tranche_name', 'id'
        ])->mapWithKeys(fn ($tranche) => [
            $tranche->id => "{$tranche->funder_name} - {$tranche->tranche_name}"
        ])->toArray();

        $endpoints = [0 => 'None Assigned'] + $endpoints;
        $tranches = [0 => 'None Assigned'] + $tranches;

        return view('components.client.client-list', [
            'clients' => $clients,
            'leadSources' => LeadSource::pluck('display_name', 'id')->toArray(),
            'urls' => $endpoints,
            'statuses' => Status::pluck('display_name', 'id')->toArray(),
            'careSettings' => Institution::orderBy('display_name')->pluck('display_name', 'id')->toArray(),
            'tags' => Tag::pluck('name', 'id')->toArray(),
            'tranches' => $tranches,
            'handlers' => User::all()->mapWithKeys(function ($user) {
                return [$user->id => $user->name_first . ' ' . $user->name_last];
            })->toArray(),
        ]);
    }

    public function clearFilters() {
        $this->reset('lead_source_id', 'url', 'date_from', 'date_to', 'status_id', 'care_setting_id');
    }

    public function checkDeleteClient($clientId) {
        $this->dispatch('swal:confirm',
            itemId: $clientId,
            title: 'Are you absolutely sure?',
            text: 'You will not be able to recover this client.'
        );
    }

    public function deleteClient($clientId) {
        $this->authorize('clients.delete');

        $client = Client::findOrFail($clientId);
        if ($this->clientService->delete($client)) {
            $this->dispatch("alert", title: $client->name_first . " " . $client->name_last . " Deleted");
        }
    }
}
