<?php

declare(strict_types=1);

namespace App\Models;

use Carbon\Carbon;
use Openguru\OpenCartFramework\QueryBuilder\Builder;
use Openguru\OpenCartFramework\QueryBuilder\Connections\ConnectionInterface;
use Openguru\OpenCartFramework\TeleCartPulse\TrackingIdGenerator;
use RuntimeException;

class TelegramCustomer
{
    private const TABLE_NAME = 'telecart_customers';

    private ConnectionInterface $database;
    private Builder $builder;

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

    /**
     * Найти запись по ID
     *
     * @param int $id ID записи
     * @return array|null Данные пользователя или null если не найдено
     */
    public function findById(int $id): ?array
    {
        return $this->builder
            ->newQuery()
            ->select(['*'])
            ->from(self::TABLE_NAME)
            ->where('id', '=', $id)
            ->firstOrNull();
    }

    /**
     * Найти запись по Telegram user ID
     *
     * @param int $telegramUserId Telegram user ID
     * @return array|null Данные пользователя или null если не найдено
     */
    public function findByTelegramUserId(int $telegramUserId): ?array
    {
        return $this->builder
            ->newQuery()
            ->select(['*'])
            ->from(self::TABLE_NAME)
            ->where('telegram_user_id', '=', $telegramUserId)
            ->firstOrNull();
    }

    /**
     * Найти запись по oc_customer_id
     *
     * @param int $customerId ID покупателя в OpenCart
     * @return array|null Данные пользователя или null если не найдено
     */
    public function findByCustomerId(int $customerId): ?array
    {
        return $this->builder
            ->newQuery()
            ->select(['*'])
            ->from(self::TABLE_NAME)
            ->where('oc_customer_id', '=', $customerId)
            ->firstOrNull();
    }

    /**
     * Создать новую запись
     *
     * @param array $data Данные для создания записи
     * @return int ID созданной записи
     * @throws RuntimeException Если не удалось создать запись
     */
    public function create(array $data): int
    {
        $data['created_at'] = Carbon::now()->toDateTimeString();
        $data['updated_at'] = Carbon::now()->toDateTimeString();
        $data['tracking_id'] = TrackingIdGenerator::generate();

        $success = $this->database->insert(self::TABLE_NAME, $data);

        if (! $success) {
            $error = $this->database->getLastError();
            $errorMessage = $error ? $error[1] : 'Unknown error';
            throw new RuntimeException("Failed to insert telegram customer. Error: {$errorMessage}");
        }

        return $this->database->lastInsertId();
    }

    /**
     * Обновить запись по Telegram user ID
     *
     * @param int $telegramUserId Telegram user ID
     * @param array $data Данные для обновления
     * @return bool true если обновление успешно
     */
    public function updateByTelegramUserId(int $telegramUserId, array $data): bool
    {
        $data['updated_at'] = Carbon::now()->toDateTimeString();

        return $this->builder->newQuery()
            ->where('telegram_user_id', '=', $telegramUserId)
            ->update(self::TABLE_NAME, $data);
    }

    /**
     * Обновить last_seen_at для пользователя
     *
     * @param int $telegramUserId Telegram user ID
     * @return bool true если обновление успешно
     */
    public function updateLastSeen(int $telegramUserId): bool
    {
        return $this->updateByTelegramUserId($telegramUserId, [
            'last_seen_at' => Carbon::now()->toDateTimeString(),
        ]);
    }

    public function increase(int $id, string $field): bool
    {
        $now = Carbon::now()->toDateTimeString();
        $table = self::TABLE_NAME;
        $sql = "UPDATE `$table` SET `$field` = `$field` + 1, updated_at = '$now' WHERE id = ?";

        return $this->database->statement($sql, [$id]);
    }
}
