<?php
/**
 * SystemAccounts service
 * Handles BANK_CONTROL_<CURRENCY> accounts safely
 */

final class SystemAccounts
{
    private mysqli $conn;

    public function __construct(mysqli $conn)
    {
        $this->conn = $conn;
    }

    /**
     * Ensure a system control account exists for a currency
     * Safe for legacy data and concurrent calls
     */
    public function ensureControl(string $currency): array
    {
        $currency   = strtoupper(trim($currency ?: 'GHS'));
        $systemCode = 'BANK_CONTROL_' . $currency;

        /* 1️⃣ Try modern system_code */
        $st = $this->conn->prepare(
            "SELECT * FROM accounts WHERE system_code = ? LIMIT 1"
        );
        $st->bind_param("s", $systemCode);
        $st->execute();
        $row = $st->get_result()->fetch_assoc();
        if ($row) {
            return $row;
        }

        /* 2️⃣ Legacy fallback by account_no */
        $st = $this->conn->prepare(
            "SELECT * FROM accounts WHERE account_no = ? LIMIT 1"
        );
        $st->bind_param("s", $systemCode);
        $st->execute();
        $row = $st->get_result()->fetch_assoc();
        if ($row) {
            $up = $this->conn->prepare(
                "UPDATE accounts
                 SET system_code = ?, account_type = 'control'
                 WHERE id = ?"
            );
            $up->bind_param("si", $systemCode, $row['id']);
            $up->execute();
            return $row;
        }

        /* 3️⃣ Create new (true first time only) */
        $accountNo = $systemCode;
        $type      = 'control';
        $balance   = 0.00;
        $status    = 'active';

        $ins = $this->conn->prepare(
            "INSERT INTO accounts
              (user_id, account_no, account_type, currency, balance, status, system_code)
             VALUES
              (?, ?, ?, ?, ?, ?, ?)"
        );

        // IMPORTANT: use a valid system user id here (see note below)
        $systemUserId = $this->getSystemUserId();

        $ins->bind_param(
            "isssdss",
            $systemUserId,
            $accountNo,
            $type,
            $currency,
            $balance,
            $status,
            $systemCode
        );
        $ins->execute();

        /* 4️⃣ Fetch again */
        $st = $this->conn->prepare(
            "SELECT * FROM accounts WHERE system_code = ? LIMIT 1"
        );
        $st->bind_param("s", $systemCode);
        $st->execute();
        $row = $st->get_result()->fetch_assoc();

        if (!$row) {
            throw new RuntimeException('Control account creation failed');
        }

        return $row;
    }

    /**
     * Returns the system user ID (required for FK safety)
     */
    private function getSystemUserId(): int
    {
        $st = $this->conn->prepare(
            "SELECT id FROM users WHERE email = 'system@localhost' LIMIT 1"
        );
        $st->execute();
        $row = $st->get_result()->fetch_assoc();

        if (!$row) {
            throw new RuntimeException(
                'System user missing. Create user system@localhost first.'
            );
        }

        return (int)$row['id'];
    }
}
