<?php
declare(strict_types=1);

use App\Modules\Accounting\ReceiptRepository;
use App\Modules\Accounting\ReceiptService;
use App\Modules\Orders\OrdersRepository;
use App\Modules\Settings\CompanySettingsRepository;
use App\Modules\Settings\ReceiptConfigRepository;

$basePath = dirname(__DIR__);

// Autoloader
$vendorAutoload = $basePath . '/vendor/autoload.php';
if (is_file($vendorAutoload)) {
    require $vendorAutoload;
} else {
    spl_autoload_register(static function (string $class) use ($basePath): void {
        $prefix = 'App\\';
        if (!str_starts_with($class, $prefix)) {
            return;
        }
        $relative = substr($class, strlen($prefix));
        $file = $basePath . '/src/' . str_replace('\\', '/', $relative) . '.php';
        if (is_file($file)) {
            require $file;
        }
    });
}

// Parse .env manually
$env = [];
$envFile = $basePath . '/.env';
if (is_file($envFile)) {
    foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
        $line = trim($line);
        if ($line === '' || str_starts_with($line, '#')) continue;
        $pos = strpos($line, '=');
        if ($pos === false) continue;
        $key = trim(substr($line, 0, $pos));
        $value = trim(trim(substr($line, $pos + 1)), "\"'");
        $env[$key] = $value;
    }
}

// Use DB_HOST_REMOTE if available, fallback to DB_HOST
$host = ($env['DB_HOST_REMOTE'] ?? '') !== '' ? $env['DB_HOST_REMOTE'] : ($env['DB_HOST'] ?? '127.0.0.1');
$port = (int) ($env['DB_PORT'] ?? 3306);
$database = $env['DB_DATABASE'] ?? 'orderpro';
$username = $env['DB_USERNAME'] ?? 'root';
$password = $env['DB_PASSWORD'] ?? '';

echo "Connecting to: {$host}:{$port}/{$database}\n";

$dsn = sprintf('mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4', $host, $port, $database);
$pdo = new PDO($dsn, $username, $password, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
]);

echo "Connected OK\n";

$orderId = (int) ($argv[1] ?? 0);
if ($orderId <= 0) {
    echo "Usage: php bin/reissue_receipt.php <order_id> [config_id]\n";
    exit(1);
}

$configId = (int) ($argv[2] ?? 0);

// Find active config if not specified
if ($configId <= 0) {
    $stmt = $pdo->prepare('SELECT id FROM receipt_configs WHERE is_active = 1 LIMIT 1');
    $stmt->execute();
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$row) {
        echo "ERROR: No active receipt config found\n";
        exit(1);
    }
    $configId = (int) $row['id'];
    echo "Using config_id: {$configId}\n";
}

// Delete existing receipts for this order
$existing = $pdo->prepare('SELECT id, receipt_number FROM receipts WHERE order_id = :order_id');
$existing->execute(['order_id' => $orderId]);
$receipts = $existing->fetchAll(PDO::FETCH_ASSOC);

if ($receipts) {
    foreach ($receipts as $r) {
        echo "Deleting receipt #{$r['id']} ({$r['receipt_number']})\n";
    }
    $pdo->prepare('DELETE FROM receipts WHERE order_id = :order_id')->execute(['order_id' => $orderId]);
} else {
    echo "No existing receipts for order #{$orderId}\n";
}

// Check delivery_price
$stmt = $pdo->prepare('SELECT delivery_price, total_with_tax FROM orders WHERE id = :id');
$stmt->execute(['id' => $orderId]);
$order = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$order) {
    echo "ERROR: Order #{$orderId} not found\n";
    exit(1);
}
echo "Order #{$orderId}: total_with_tax={$order['total_with_tax']}, delivery_price={$order['delivery_price']}\n";

// Issue new receipt
$receiptRepo = new ReceiptRepository($pdo);
$configRepo = new ReceiptConfigRepository($pdo);
$companyRepo = new CompanySettingsRepository($pdo);
$ordersRepo = new OrdersRepository($pdo);
$service = new ReceiptService($receiptRepo, $configRepo, $companyRepo, $ordersRepo);

try {
    $result = $service->issue([
        'order_id' => $orderId,
        'config_id' => $configId,
        'created_by' => null,
    ]);
    echo "SUCCESS: Receipt issued: {$result['receipt_number']}, total_gross: {$result['total_gross']}\n";
} catch (Throwable $e) {
    echo "ERROR: {$e->getMessage()}\n";
    exit(1);
}
