<?php

namespace Mtc\Plugins\MtcUnioIntegration\Classes;

use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Mtc\Modules\Members\Models\Member;
use Mtc\Modules\MtcUnio\Classes\UnioApi;
use Mtc\Modules\MtcUnio\Interfaces\UnioApiRequestable;
use Mtc\Shop\Order;

class QueueMessageFromUnio extends QueueMessage implements UnioApiRequestable
{

    protected $table = 'unio__queue_messages_from_unio';

    // We don't have 'updated_at' field in the table.
    public $timestamps = false;

    protected $fillable = [
        'entity_type',
        'entity_id'
    ];

    const ENTITY_CUSTOMER = 'customer';
    const ENTITY_ORDER = 'order';
    const ENTITY_MESSAGE = 'message';


    public static function get_available_entity_types()
    {
        return [
            self::ENTITY_CUSTOMER,
            self::ENTITY_ORDER,
            self::ENTITY_MESSAGE,
        ];
    }


    private $rules = [
        'entity_id' => [ 'required' , 'integer' ],
        'entity_type' => [ 'required' ],
    ];

    public function validate()
    {
        $this->rules['entity_type'][] = Rule::in(self::get_available_entity_types());

        return Validator::make($this->attributes, $this->rules);
    }



    public function saveResponse(string $response, $append = false) : void
    {
        if ($append) {
            $this->response .= $response;
        } else {
            $this->response = $response;
        }
        $this->save();
    }


    public function processResponse() : void
    {
        $response = json_decode($this->response, true);
        $response_body = Arr::get($response, 'body');

        switch ($this->entity_type) {
            case self::ENTITY_CUSTOMER:
                $this->processResponseWithCustomerData($response_body);
                break;

            case self::ENTITY_ORDER:
                $this->processResponseWithOrderData($response_body);
                break;
        }

        $this->processed_at = date('Y-m-d H:i');
        $this->save();
    }

    private function processResponseWithCustomerData(array $data, $update_if_existing = true, $update_if_new = true)
    {
        $member_id = Arr::get($data, 'id');
        $unio_internal_id = Arr::get($data, 'internalId');
        Arr::set($data, 'unio_internal_id', $unio_internal_id);

        if ($member_id) {
            $member = Member::findOrFail($member_id);
        } elseif ($unio_internal_id) {
            $member = Member::query()->where('unio_internal_id', $unio_internal_id)->first();
        }

        if (! $member) {
            $member = new Member([
                'is_external' => true,
                'is_activated' => false,
            ]);
        }

        $has_unsynced_messages = QueueMessageToUnio::pending()
            ->where('entity_type', QueueMessageToUnio::ENTITY_MEMBER)
            ->where('entity_id', $member->id)
            ->count()
        ;

        if (! $has_unsynced_messages) {
            if ($member->exists) {
                $update_if_existing and $member->update_from_input($data);
            } else {
                $update_if_new and $member->update_from_input($data);
            }
        }

        return $member;
    }

    private function processResponseWithOrderData(array $data)
    {
        // NHS prescription processing removed
    }


    public function getPayloadData() : array
    {
        return [];
    }


    public function getQueryParams() : array
    {
        return [
            'id' => $this->entity_id
        ];
    }


    public function getEndpointName() : string
    {
        $endpoint_name = '';

        switch ($this->entity_type) {
            case self::ENTITY_CUSTOMER:
                $endpoint_name = UnioApi::ENDPOINT_CUSTOMER_GET;
                break;

            case self::ENTITY_ORDER:
                $endpoint_name = UnioApi::ENDPOINT_ORDER_GET;
                break;
        }

        return $endpoint_name;
    }


    public function getMethodName() : string
    {
        return 'GET';
    }
}
