<?php

namespace App\Services;

use Openguru\OpenCartFramework\QueryBuilder\Builder;
use Openguru\OpenCartFramework\QueryBuilder\Connections\ConnectionInterface;
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;

class OcCustomerService
{
    private Builder $builder;
    private ConnectionInterface $database;

    public function __construct(Builder $builder, ConnectionInterface $database)
    {
        $this->builder = $builder;
        $this->database = $database;
    }

    public function create(array $orderData, ?int $telecartCustomerId): ?int
    {
        $customerData = [
            'customer_group_id' => $orderData['customer_group_id'],
            'store_id' => $orderData['store_id'],
            'language_id' => $orderData['language_id'],
            'firstname' => $orderData['firstname'] ?? '',
            'lastname' => $orderData['lastname'] ?? '',
            'email' => $orderData['email'] ?? '',
            'telephone' => $orderData['telephone'] ?? '',
            'fax' => $orderData['fax'] ?? '',
            'password' => bin2hex(random_bytes(16)),
            'salt' => bin2hex(random_bytes(9)),
            'ip' => $orderData['ip'] ?? '',
            'status' => 1,
            'safe' => 0,
            'token' => bin2hex(random_bytes(32)),
            'code' => '',
            'date_added' => $orderData['date_added'],
        ];

        $this->database->insert(db_table('customer'), $customerData);
        $lastInsertId = $this->database->lastInsertId();

        if ($telecartCustomerId) {
            $this->builder
                ->where('id', '=', $telecartCustomerId)
                ->update('telecart_customers', [
                    'oc_customer_id' => $lastInsertId,
                ]);
        }

        return $lastInsertId;
    }

    public function findByTelecartCustomerId(int $telegramCustomerId): ?array
    {
        return $this->builder->newQuery()
            ->select(['oc_customers.*'])
            ->from(db_table('customer'), 'oc_customers')
            ->join('telecart_customers', function (JoinClause $join) {
                $join->on('telecart_customers.oc_customer_id', '=', 'oc_customers.customer_id');
            })
            ->where('telecart_customers.id', '=', $telegramCustomerId)
            ->firstOrNull();
    }

    public function findById(int $ocCustomerId): ?array
    {
        return $this->builder->newQuery()
            ->select(['oc_customers.*'])
            ->from(db_table('customer'), 'oc_customers')
            ->where('oc_customers.customer_id', '=', $ocCustomerId)
            ->firstOrNull();
    }

    public function findOrCreateByTelecartCustomerId(int $telecartCustomerId, array $orderData): ?array
    {
        $ocCustomer = $this->findByTelecartCustomerId($telecartCustomerId);

        if (! $ocCustomer) {
            $ocCustomerId = $this->create($orderData, $telecartCustomerId);

            return $this->findById($ocCustomerId);
        }

        return $ocCustomer;
    }
}
