<?php

namespace Modules\Bitrix\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Hash;

use Modules\Main\Models\Deal\Deal;
use Modules\Main\Models\Deal\Client;
use Modules\Main\Models\Deal\DealClients;
use Modules\Main\Models\Agent\Agent;
use Modules\Main\Models\Company\Company;
use Modules\Main\Models\Complex;

class BitrixId extends Model
{
    use HasFactory;

    protected $table = 'bx_ids';
    protected $fillable = [
        'bx_id'
    ];
    public function bitrixable(): MorphTo
    {
        return $this->morphTo();
    }

    protected static function getSender(BitrixId $bitrixId)
    {
        $object = false;
        $sender = false;
        switch ($bitrixId->bitrixable_type) {
            case Deal::class:
                $deal = Deal::findOrFail($bitrixId->bitrixable_id);
                $sender = new SendDeal($deal);
                $object = $deal;
                break;
            case Agent::class:
                $agent = Agent::findOrFail($bitrixId->bitrixable_id);
                $sender = new SendAgent($agent);
                break;
            case DealClients::class:
                $dealClient = DealClients::findOrFail($bitrixId->bitrixable_id);
                $client = $dealClient->client;
                $sender = new SendClient($client);
                $bitrixId->bitrixable_type = Client::class;
                $bitrixId->bitrixable_id = $client->id;
                $object = $client;
                break;
            case Company::class:
                $company = Company::findOrFail($bitrixId->bitrixable_id);
                $sender = new SendCompany($company);
                $object = $company;
                break;
        }
        return $sender;
    }

    protected static function booted()
    {
        static::creating(function (BitrixId $bitrixId) {
            if ($bitrixId->bx_id) {
                return;
            }
            $sender = self::getSender($bitrixId);
            if ($sender) {
                $bitrixId->token = hash('sha256', $bitrixId->bx_id . $bitrixId->bitrixable_id . $bitrixId->bitrixable_type);
                $sender->setCallbackUrl(
                    route('api.bx.action', [
                        'token' => $bitrixId->token
                    ])
                );
                $result = $sender->send();
                if ($result) {
                    $id = $sender->resultData['id'];
                    $bitrixId->bx_id = $id;
                    return;
                };
            }
            throw new \Exception('Error of bitrix identifier getter for ' . $bitrixId->bitrixable_type . ' with id ' . $bitrixId->bitrixable_id);
        });

        //Агентов и клиентов отправляю после создания,
        //т.к. на стороне битрикса нужна связка сущностей
        //по созданной сделке
        static::created(function (BitrixId $bitrixId) {
            if (!$bitrixId->bx_id) {
                return;
            }
            switch ($bitrixId->bitrixable_type) {
                case Deal::class:
                    $deal = Deal::findOrFail($bitrixId->bitrixable_id);
                    $agentAppender = new SendDealAgent($deal);
                    $agentAppender->send();
                    break;
                case Client::class:
                    $client = Client::findOrFail($bitrixId->bitrixable_id);
                    if ($dealClient = DealClients::where('client_id', $client->id)->orderByDesc('id')->first()) {
                        $clientAppender = new SendDealClient(Deal::find($dealClient->deal_id), $client);
                        $result = $clientAppender->send();
                    }
                    break;
            }

        });
    }
}
