<?php

namespace App\Livewire;

use Livewire\Component;
use Livewire\WithPagination;
use Livewire\WithoutUrlPagination;


use App\Models\User;
use Modules\Main\Models\Deal\Client;
use Modules\Main\Models\Agent\Agent;
use Modules\Main\Models\Company\CompanyAdmin;
use Modules\Main\Models\Deal\Deal;
use Modules\Main\Models\Deal\DealStatus;
use Modules\CityManager\Models\CityManager;

use Livewire\Attributes\On;

class ClientsTable extends Component
{
    public $status;
    public $count;
    public $mode; //short || full
    public $filter = [];
    public $clientsCount;
    public $currentPage;

    public function mount($status = null, $count = 10, $mode = 'full')
    {
        $this->status = $status;
        $this->count = $count;
        $this->mode = $mode;
        $this->filter = [];
    }

    public function goToPage($page)
    {
        $this->currentPage = $page;
    }

    #[On('clientsTableFilterUpdated')]
    public function appendFilter($filter)
    {
        if ($filter) {
            $this->filter = $filter;
        } else {
            $this->filter = [];
        }
        $this->render();
    }
    #[On('clientCreated')]
    public function getDeals()
    {
        $deals = false;
        $clients = false;
        $user = auth()->user();

        if ($cityManager = CityManager::where('user_id', auth()->id())->first()) {
            $companies = $cityManager->city->companies->pluck('id');
            $deals = Deal::whereIn('agent_id', function ($query) use ($companies) {
                $query->select('id');
                $query->from('agents');
                $query->whereIn('company_id', $companies);
            });
        } else if ($company = AdminCompanyOfUser()) {
            $deals = Deal::whereIn('agent_id', function ($query) use ($company) {
                $query->select('id');
                $query->from('agents');
                $query->where('company_id', $company->id);
            });
        } elseif ($agent = Agent::where('user_id', $user->id)->first()) {
            $deals = Deal::where('agent_id', $agent->id);
        }
        if (array_key_exists('status', $this->filter)) {
            $deals->where('status', $this->filter['status']);
        }

        if (array_key_exists('complexes', $this->filter)) {
            $complexes = [];
            foreach ($this->filter['complexes'] as $selectedComplex) {
                $complexes[] = $selectedComplex['id'];
            }
            $deals->whereIn('complex_id', $complexes);
        }

        if (!$deals) {
            return Client::where('id', 0);
        }
        return $deals;
    }

    function getClients()
    {
        $deals = $this->getDeals();
        $clients = Client::join('deal_clients', 'users.id', '=', 'deal_clients.client_id')
            ->whereIn('users.id', function ($query) use ($deals) {
                $query->select('client_id')
                    ->from('deal_clients')
                    ->whereIn('deal_id', $deals->get()->pluck('id'));
            })
            ->orderBy('deal_clients.id', 'desc')
            ->with('deals');
        $clients->select('users.id', 'users.name', 'users.phone', 'users.email');
        $clients->orderBy('name');
        $clients->join('deals', 'deal_clients.deal_id', '=', 'deals.id');
        if (array_key_exists('status', $this->filter)) {
            $clients->where('deals.status', $this->filter['status']);
        }

        if (array_key_exists('complexes', $this->filter)) {
            $complexes = [];
            foreach ($this->filter['complexes'] as $selectedComplex) {
                $complexes[] = $selectedComplex['id'];
            }
            $clients->whereIn('deals.complex_id', $complexes);
        }

        if (array_key_exists('search', $this->filter) && $searchString = trim($this->filter['search'])) {
            $searchString = mb_strtolower(trim($this->filter['search']));
            // $clients->whereFullText(['name', 'phone', 'email', 'normalized_name', 'normalized_phone'], $searchString);
            $clients->where(function ($query) use ($searchString) {
                $query->where('normalized_name', 'like', "%{$searchString}%");
                $query->orWhere('email', 'like', "%{$searchString}%", false);
                if ($phoneFormatted = $this->normilizePhone($searchString)) {
                    $query->orWhere('normalized_phone', 'like', "%{$phoneFormatted}%");
                }
            });
            
        }

        if (array_key_exists('status', $this->filter) && $this->status == DealStatus::UNIQUE) {
            $clients = $clients->whereHas('deals', function ($query) {
                $query->where('status', DealStatus::UNIQUE);
            });
        } elseif (array_key_exists('status', $this->filter) && $this->status == DealStatus::NOT_UNIQUE) {
            $clients = $clients->whereHas('deals', function ($query) {
                $query->whereIn('status', [DealStatus::MODERATION, DealStatus::NEW, DealStatus::NOT_UNIQUE]);
            });
        }
        return $clients;
    }

    private function normilizePhone($value)
    {
        $digits = preg_replace('/\D+/', '', $value);

        if (strlen($digits) >= 2 && ($digits[0] === '7' || $digits[0] === '8')) {
            return substr($digits, 1);
        }

        return $digits;
    }
    public function render()
    {
        $clients = $this->getClients();
        $clients->groupBy('users.id', 'users.name', 'users.phone', 'users.email');
        if ($this->clientsCount != $clients->count()) {
            $this->clientsCount = $clients->count();
            $this->currentPage = 1;
        };
        $clients = $clients->skip(($this->currentPage - 1) * $this->count)->take($this->count)->get();
        return view(
            'livewire.clients-table',
            [
                'clients' => $clients,
                'statuses' => DealStatus::class
            ]
        );
    }
}
