<?php

namespace Shm\ShmPayment\TBankPayment;

use Shm\Shm;
use Shm\ShmDB\mDB;
use Shm\ShmPayment\TBankPayment\TBankCollections\TCustomerCards;
use Shm\ShmTypes\StructureType;

class TBankCustomer
{
    public $customerID = null;
    public $customerPhone = null;
    public $customerEmail = null;
    public $customerStructure = null;


    public static function create(StructureType $customerStructure, $customer_id)
    {
        return new self($customerStructure, $customer_id);
    }

    public function __construct(StructureType $customerStructure, $customer_id)
    {



        if (!TBankPayment::$terminalKey || !TBankPayment::$terminalPassword) {
            throw new \Exception("Terminal key or password is not set");
        }


        if (!TBankPayment::$terminalTaxation) {
            throw new \Exception("Terminal taxation is not set");
        }

        if (!TBankPayment::$terminalTaxRate) {
            throw new \Exception("Terminal tax rate is not set");
        }

        $this->customerStructure = $customerStructure;

        $phoneField = $customerStructure->findItemByType(Shm::phone());
        if (!$phoneField) {
            throw new \Exception("Phone field not found");
        }



        $customer = $customerStructure->findOne([
            "_id" => mDB::id($customer_id)
        ]);

        if (!$customer) {
            throw new \Exception("Customer not found");
        }
        $this->updateCustomerPhoneAndEmail($customerStructure, $customer_id);


        $this->customerID = mDB::id($customer['_id']);
    }

    private function updateCustomerPhoneAndEmail(StructureType $customerStructure, $customer_id)
    {

        $phoneField = $customerStructure->findItemByType(Shm::phone());

        $emailField = $customerStructure->findItemByType(Shm::email());

        $customer = $customerStructure->findOne(
            [
                "_id" => mDB::id($customer_id),
            ]
        );

        if ($phoneField && isset($customer[$phoneField->key]) && $customer[$phoneField->key]) {
            $this->customerPhone = '+' . $customer[$phoneField->key];
        }
        if ($emailField && isset($customer[$emailField->key]) && $customer[$emailField->key]) {
            $this->customerEmail = $customer[$emailField->key];
        }
    }



    public function getCustomerKey()
    {
        return md5($this->customerID . $this->customerStructure->collection . TBankPayment::$terminalKey);
    }

    public function removeCard($CardId)
    {

        $response = TBankPayment::sendRequest('RemoveCard', [
            "CardId" => $CardId,
            "CustomerKey" => $this->getCustomerKey(),
        ]);

        return $response;
    }


    public function updateCards()
    {
        $response = TBankPayment::sendRequest('GetCardList', [
            "CustomerKey" => $this->getCustomerKey(),
        ]);


        $cards = $response ?? [];

        foreach ($cards as $card) {

            TCustomerCards::updateOne(
                [
                    'CardId' => $card['CardId'],
                    'deleted_at' => ['$exists' => false],
                    "owner" => $this->customerID,
                    "ownerCollection" => $this->customerStructure->collection,
                    'TerminalKey' => TBankPayment::$terminalKey,

                ],
                [

                    '$set' => [
                        ...$card,
                        'TerminalKey' => TBankPayment::$terminalKey,
                        "owner" => $this->customerID,
                        "ownerCollection" => $this->customerStructure->collection,
                    ]

                ],
                [
                    'upsert' => true,
                ]
            );
        }
    }

    public  function validCard($card_id): bool
    {

        $findCard = TCustomerCards::findOne([
            '_id' => mDB::id($card_id),
            'owner' => $this->customerID
        ]);

        if (! $findCard) {
            return false;
        }



        $response = TBankPayment::sendRequest('GetCardList', [
            "CustomerKey" => $this->getCustomerKey(),
        ]);



        $cards = $response ?? [];

        if (!$cards || count($cards) == 0) {
            return false;
        }

        foreach ($cards as $card) {

            if ($card['CardId'] == $findCard->CardId) {
                return true;
            }
        }

        return false;
    }
}