<?php

namespace App\Modules\Lead\Application\CreateOrUpdate;

use App\Modules\Lead\Application\Create\LeadInserter;
use App\Modules\Lead\Application\Index\LeadIndexer;
use App\Modules\Lead\Application\Update\LeadUpdater;
use App\Modules\Lead\Domain\IdLead;
use App\Modules\Lead\Domain\Lead;
use App\Modules\Lead\Domain\LeadAddress;
use App\Modules\Lead\Domain\LeadContactName;
use App\Modules\Lead\Domain\LeadContactPhone;
use App\Modules\Lead\Domain\LeadEmail;
use App\Modules\Lead\Domain\LeadGender;
use App\Modules\Lead\Domain\LeadLastName;
use App\Modules\Lead\Domain\LeadName;
use App\Modules\Lead\Domain\LeadNoDocument;
use App\Modules\Lead\Domain\LeadPhone;
use App\Modules\Lead\Domain\LeadPhoneCode;
use App\Modules\Lead\Domain\LeadStatus;
use App\Modules\Lead\Domain\LeadType;
use App\Modules\Shared\Domain\Bus\Query\QueryHandler;
use App\Modules\TypeDocument\Domain\IdTypeDocument;
use App\Modules\UserCountry\Domain\IdUserCountry;

final class LeadInsertOrUpdaterQueryHandler implements QueryHandler
{
    public function __construct(
        private LeadInserter $inserter,
        private LeadUpdater $updater,
        private LeadIndexer $indexer
    ) {
    }

    public function __invoke(LeadInsertOrUpdaterQuery $query): LeadInsertOrUpdaterResponse
    {
        if ($query->id() === 0) {
            $model = new Lead(
                new LeadName($query->name()),
                new LeadLastName($query->lastName()),
                new LeadGender(LeadGender::MALE),
                new LeadEmail($query->email()),
                new LeadPhoneCode($query->phoneCode()),
                new LeadPhone($query->phone()),
                new LeadNoDocument(''),
                new LeadAddress(''),
                new LeadContactName(''),
                new LeadContactPhone(''),
                new LeadType(LeadType::WEB),
                new LeadStatus(LeadStatus::ACTIVE),
                new IdTypeDocument($query->idTypeDocument()),
                new IdUserCountry($query->idUserCountry()),
            );
            $insert = $this->inserter->__invoke($model);
            return new LeadInsertOrUpdaterResponse(new IdLead($insert->response()['Response_Data']['Id']));
        } else {
            $index = $this->indexer->__invoke(new IdLead($query->id()));
            $model = new Lead(
                new LeadName($query->name()),
                new LeadLastName($query->lastName()),
                new LeadGender($index->response()['Response_Data']->Lead_Gender),
                new LeadEmail($query->email()),
                new LeadPhoneCode($query->phoneCode()),
                new LeadPhone($query->phone()),
                new LeadNoDocument($query->noDocument()),
                new LeadAddress($index->response()['Response_Data']->Lead_Address),
                new LeadContactName($index->response()['Response_Data']->Lead_ContactName),
                new LeadContactPhone($index->response()['Response_Data']->Lead_ContactPhone),
                new LeadType($index->response()['Response_Data']->Lead_Type),
                new LeadStatus($index->response()['Response_Data']->Lead_Status),
                new IdTypeDocument($query->idTypeDocument()),
                new IdUserCountry($query->idUserCountry()),
            );
            $this->updater->__invoke($model);
            return new LeadInsertOrUpdaterResponse($model->getId());
        }
    }
}
