<?php

namespace Modules\ClientCreateForm\Http\Livewire;

use Exception;
use Laravel\Prompts\FormStep;
use Livewire\Component;
use Livewire\Attributes\Validate;
use Livewire\Attributes\On;


use Modules\Main\Models\Deal\Deal;
use Modules\Main\Models\Deal\Client;
use Modules\Main\Models\Deal\DealClients;
use Modules\Plan7\Models\DealPlan7;
class ClientCreateLivewire extends Component
{

    public $status;
    public $availableAgents;
    public $complexes;
    public $maxContactsCount;
    public $maxContactPhonesCount;
    /////////////////////
    public $selectedObjects = [];
    public $agentId;
    public $contacts;
    public $objects = [];
    public $complexId;
    public $plan7Room = false;
    ////////////////////
    public $currentContactIndex;
    public $contactLabels;
    public $bitrixId;

    protected function rules()
    {
        return [
            'contacts.*' => ['required', 'min:1'],
            'contacts.*.firstName' => ['required', 'string', 'max:50'],
            'contacts.*.secondName' => ['string', 'max:50'],
            'contacts.*.phones.*' => 'required|string|regex:/^(\+7)([(]{1})([0-9]{3})([)]{1})([\s]{1})([0-9]{3})([-]{1})([0-9]{2})([-]{1})([0-9]{2})/',
            'selectedObjects' => 'required',
            'agentId' => ['required'],
        ];
    }
    protected function messages()
    {
        return [
            'contacts.*.firstName.reqired' => 'Необходимо указать имя (отчество) клиента',
            'contacts.*.secondName.reqired' => 'Необходимо указать фамилию клиента',
            'contacts.*.firstName.max' => 'Указанное имя клиента слишком длинное',
            'contacts.*.secondName.max' => 'Указанное имя клиента слишком длинное',
            'contacts.*.phones.*.reqired' => 'Необходимо указать номер телефона клиента',
            'contacts.*.phones.*.regex' => 'Указанный номер телефона некорректный',
            'selectedObjects.required' => 'Необходимо выбрать хотя бы один интересующий ЖК',

        ];
    }
    public function mount()
    {
        $this->status = FormStatus::NEW;
        $this->complexes = GetAvailableComplexes();
        $this->availableAgents = GetAvailableAgents();
        $this->maxContactPhonesCount = 1;
        $this->contacts = [];
        $this->contactLabels = ['Основной контакт', 'Супруг/супруга'];

        if (array_key_exists('contact_form_count_max', DESIGN_PARAMETERS) && (int) DESIGN_PARAMETERS['contact_form_count_max'] > 0) {
            $this->maxContactsCount = (int) DESIGN_PARAMETERS['contact_form_count_max'];
        } else {
            $this->maxContactsCount = 2;
        }

        if (array_key_exists('contact_form_count', DESIGN_PARAMETERS) && (int) DESIGN_PARAMETERS['contact_form_count'] > 0) {
            for ($tabsCount = 1; $tabsCount <= (int) DESIGN_PARAMETERS['contact_form_count']; $tabsCount++) {
                $this->addContact();
            }
        } else {
            $this->addContact();
            $this->addContact();//по-умолчанию сразу выводить супруга
        }

        if (count($this->availableAgents) == 1) //чтобы не выводить в форму
        {                                              //и не заставлять пользователя указывать вручную
            $this->agentId = $this->availableAgents[0]['id'];
        }

        $this->setCurrentContactIndex(0);
    }

    /**
     * Метод срабатывает, когда пользователь нажимает в форме
     * на кнопку "Добавить супруга"
     * @return void
     */
    public function addContact()
    {
        if (!isset($this->contacts)) {
            $this->contacts = [];
        }
        if ($this->maxContactsCount > count($this->contacts)) {
            $this->contacts[] = [
                'firstName' => '',
                'secondName' => '',
                'phones' => ['']
            ];
        }
        $this->setCurrentContactIndex(count($this->contacts) - 1);
    }
    /**
     * Метод срабатывает, когда пользователь нажимает кнопку "Удалить контакт"
     * Кнопка доступна на всех вкладках, кроме первой
     * @param mixed $index Индекс контакта по порядку следования на вкладках
     * @return void
     */
    public function deleteContact($index = false)
    {
        if ($index === false) {
            $index = $this->currentContactIndex;
        }
        if ($index > 0) {
            unset($this->contacts[$index]);
            $this->contacts = array_values($this->contacts);
            $this->setCurrentContactIndex($index - 1);
        }
    }
    /**
     * Вызвается при переходе пользователя по вкладкам
     * @param mixed $index
     * @return void
     */
    public function setCurrentContactIndex($index)
    {
        $this->currentContactIndex = $index;
        $this->updated('currentContactIndex');
    }
    /**
     * Вызывается, когда пользователь нажимает на кнопку
     * "Добавить супруга" на первой вкладке
     * @return void
     */
    public function toggleSecondContact()
    {
        if ($this->currentContactIndex == 0) {
            if (count($this->contacts) == 2) {
                $this->deleteContact(1);
            } elseif (count($this->contacts) == 1) {
                $this->addContact();
            }
        }
    }
    /**
     * Вызывается, когда пользователь нажимает на кнопку "добавить телефон"
     * на вкладке любого из контактов
     * @return void
     */
    public function addPhoneForCurrentContact()
    {
        if (count($this->contacts[$this->currentContactIndex]['phones']) < $this->maxContactPhonesCount) {
            $this->contacts[$this->currentContactIndex]['phones'][] = '';
        }
    }

    public function removeObject($complexId) {
        unset($this->selectedObjects[$complexId]);
    }
    public function updated($propertyName)
    {
        $this->status = FormStatus::IN_PROCESS;
        $this->validateOnly($propertyName);
        foreach ($this->selectedObjects as $complexId => $selectedObject) {
            if ($selectedObject == null) {
                unset($this->selectedObjects[$complexId]);
            }
        }
        if ($propertyName === 'complexId') {
            $this->dispatch('client_form_complex_updated', complexId: $this->complexId);
        }
        try {
            $this->validate();
            $this->status = FormStatus::READY;
        } catch (\Exception $e) {
            $this->status = FormStatus::IN_PROCESS;
        }
    }
    #[On('plan7_selector_set_room')]
    public function setPlan7Room($data)
    {
        if ($data) {
            $this->selectedObjects[$data['complexId']] = $data['room'];
        }
    }
    public function render()
    {
        return view(
            'clientcreateform::livewire.form'
        );
    }
    public function rendered()
    {
        $this->dispatch('phoneInputAdded');

    }
    public function resetData()
    {
        $this->mount();
    }
    public function back()
    {
        $this->status = FormStatus::IN_PROCESS;
    }

    public function save()
    {
        $hasErrors = false;
        foreach ($this->selectedObjects as $complexId=>$room) {
            if ($this->createDeal($complexId, $room)) {
                unset($this->selectedObjects[$complexId]);
            } else {
                $hasErrors = true;
            }
        }
        if ($hasErrors) {
            return $this->status = FormStatus::ERROR;
        }
        $this->status = FormStatus::SUCCESS;
    }

    private function createDeal($complexId, $room)
    {
        if (
            !$deal = Deal::create([
                'agent_id' => $this->agentId,
                'complex_id' => $complexId,
                'plan7_data' => (is_array($room) && array_key_exists('id', $room)) ? json_encode($room) : null
            ])
        ) {
            return false;
        }

        foreach ($this->contacts as $contact) {
            if (
                !$newUser = Client::updateOrCreate(
                    ['phone' => $contact['phones'][0]],
                    [
                        'name' => trim($contact['firstName'] . ' ' . $contact['secondName']),
                        'phone' => $contact['phones'][0]
                    ]
                )
            ) {
                return false;
            }
            if (
                !$dealClient = DealClients::firstOrCreate([
                    'deal_id' => $deal->id,
                    'client_id' => $newUser->id
                ])
            ) {
                return false;
            }
        }
        $this->dispatch('clientCreated');
        return true;
    }
}