<?php

namespace App\Core;

/**
 * مدير الحسابات المالية للمرضى
 * يربط الفواتير والطلبات بالحسابات المالية
 */
class AccountManager
{
    private \PDO $db;
    private int $tenantId;

    public function __construct(\PDO $db, int $tenantId)
    {
        $this->db = $db;
        $this->tenantId = $tenantId;
    }

    /**
     * إنشاء أو جلب حساب المريض
     */
    public function getOrCreateAccount(int $patientId): ?int
    {
        try {
            $this->db->query('SELECT id FROM patient_accounts LIMIT 1');
            
            $stmt = $this->db->prepare('SELECT id FROM patient_accounts WHERE patient_id = ? AND tenant_id = ?');
            $stmt->execute([$patientId, $this->tenantId]);
            $account = $stmt->fetch();
            
            if ($account) {
                return (int)$account['id'];
            }
            
            // إنشاء حساب جديد
            $stmt = $this->db->prepare('INSERT INTO patient_accounts (patient_id, tenant_id, account_balance, currency) VALUES (?, ?, 0.00, "IQD")');
            $stmt->execute([$patientId, $this->tenantId]);
            return (int)$this->db->lastInsertId();
        } catch (\Throwable $e) {
            return null;
        }
    }

    /**
     * ربط فاتورة بحساب المريض
     */
    public function linkInvoiceToAccount(int $invoiceId, int $orderId, int $patientId, float $totalAmount, float $paidAmount, string $invoiceNumber, string $currency = 'IQD'): bool
    {
        try {
            $this->db->query('SELECT id FROM account_invoices LIMIT 1');
            
            $accountId = $this->getOrCreateAccount($patientId);
            if (!$accountId) return false;
            
            $remainingAmount = $totalAmount - $paidAmount;
            $status = $remainingAmount <= 0 ? 'paid' : ($paidAmount > 0 ? 'partial' : 'pending');
            
            // التحقق من وجود الفاتورة مسبقاً
            $stmt = $this->db->prepare('SELECT id FROM account_invoices WHERE invoice_id = ? OR order_id = ? LIMIT 1');
            $stmt->execute([$invoiceId, $orderId]);
            if ($stmt->fetch()) {
                // تحديث الفاتورة الموجودة
                $stmt = $this->db->prepare('UPDATE account_invoices 
                    SET account_id = ?, total_amount = ?, paid_amount = ?, remaining_amount = ?, status = ?, currency = ?
                    WHERE invoice_id = ? OR order_id = ?');
                $stmt->execute([
                    $accountId, $totalAmount, $paidAmount, $remainingAmount, $status, $currency,
                    $invoiceId, $orderId
                ]);
            } else {
                // إنشاء فاتورة جديدة
                $stmt = $this->db->prepare('INSERT INTO account_invoices 
                    (account_id, invoice_id, order_id, invoice_number, total_amount, paid_amount, remaining_amount, currency, invoice_date, status)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURDATE(), ?)');
                $stmt->execute([
                    $accountId, $invoiceId, $orderId, $invoiceNumber, $totalAmount, $paidAmount, $remainingAmount, $currency, $status
                ]);
            }
            
            // تحديث رصيد الحساب (إذا كانت الفاتورة غير مدفوعة)
            if ($remainingAmount > 0) {
                $this->updateAccountBalance($accountId, -$remainingAmount, 'invoice', 'فاتورة: ' . $invoiceNumber);
            }
            
            return true;
        } catch (\Throwable $e) {
            error_log("AccountManager::linkInvoiceToAccount error: " . $e->getMessage());
            return false;
        }
    }

    /**
     * تحديث رصيد الحساب
     */
    public function updateAccountBalance(int $accountId, float $amount, string $transactionType = 'adjustment', ?string $description = null): bool
    {
        try {
            $this->db->query('SELECT id FROM account_transactions LIMIT 1');
            
            $this->db->beginTransaction();
            
            $stmt = $this->db->prepare('SELECT account_balance FROM patient_accounts WHERE id = ?');
            $stmt->execute([$accountId]);
            $account = $stmt->fetch();
            
            if (!$account) {
                $this->db->rollBack();
                return false;
            }
            
            $balanceBefore = (float)$account['account_balance'];
            $balanceAfter = $balanceBefore + $amount;
            
            // تحديث الرصيد
            $stmt = $this->db->prepare('UPDATE patient_accounts SET account_balance = ? WHERE id = ?');
            $stmt->execute([$balanceAfter, $accountId]);
            
            // إنشاء معاملة
            $stmt = $this->db->prepare('INSERT INTO account_transactions 
                (account_id, transaction_type, amount, balance_before, balance_after, description)
                VALUES (?, ?, ?, ?, ?, ?)');
            $stmt->execute([
                $accountId, $transactionType, abs($amount), $balanceBefore, $balanceAfter, $description
            ]);
            
            $this->db->commit();
            return true;
        } catch (\Throwable $e) {
            if ($this->db->inTransaction()) $this->db->rollBack();
            error_log("AccountManager::updateAccountBalance error: " . $e->getMessage());
            return false;
        }
    }

    /**
     * تسجيل دفعة على فاتورة
     */
    public function recordPayment(int $accountId, int $invoiceId, float $amount, string $paymentMethod, ?string $receiptNumber = null): bool
    {
        try {
            $this->db->query('SELECT id FROM account_payments LIMIT 1');
            $this->db->query('SELECT id FROM account_transactions LIMIT 1');
            
            $this->db->beginTransaction();
            
            // جلب الحساب
            $stmt = $this->db->prepare('SELECT account_balance FROM patient_accounts WHERE id = ?');
            $stmt->execute([$accountId]);
            $account = $stmt->fetch();
            if (!$account) {
                $this->db->rollBack();
                return false;
            }
            
            $balanceBefore = (float)$account['account_balance'];
            $balanceAfter = $balanceBefore + $amount;
            
            // تحديث الرصيد
            $stmt = $this->db->prepare('UPDATE patient_accounts SET account_balance = ? WHERE id = ?');
            $stmt->execute([$balanceAfter, $accountId]);
            
            // إنشاء معاملة
            $stmt = $this->db->prepare('INSERT INTO account_transactions 
                (account_id, transaction_type, amount, balance_before, balance_after, description, payment_method, receipt_number)
                VALUES (?, "payment", ?, ?, ?, ?, ?, ?)');
            $description = 'دفعة على فاتورة #' . $invoiceId;
            $stmt->execute([
                $accountId, $amount, $balanceBefore, $balanceAfter, $description, $paymentMethod, $receiptNumber
            ]);
            $transactionId = (int)$this->db->lastInsertId();
            
            // إنشاء سجل الدفعة
            $stmt = $this->db->prepare('INSERT INTO account_payments 
                (account_id, invoice_id, transaction_id, amount, payment_method, payment_date, receipt_number)
                VALUES (?, ?, ?, ?, ?, NOW(), ?)');
            $stmt->execute([
                $accountId, $invoiceId, $transactionId, $amount, $paymentMethod, $receiptNumber
            ]);
            
            // تحديث الفاتورة (استخدام invoice_id لأن $invoiceId يشير لمعرّف الفاتورة الأصلية)
            $stmt = $this->db->prepare('SELECT * FROM account_invoices WHERE invoice_id = ?');
            $stmt->execute([$invoiceId]);
            $invoice = $stmt->fetch();
            if ($invoice) {
                $newPaid = (float)$invoice['paid_amount'] + $amount;
                $remaining = (float)$invoice['total_amount'] - $newPaid;
                $status = $remaining <= 0 ? 'paid' : ($newPaid > 0 ? 'partial' : 'pending');
                
                $stmt = $this->db->prepare('UPDATE account_invoices SET paid_amount = ?, remaining_amount = ?, status = ? WHERE invoice_id = ?');
                $stmt->execute([$newPaid, $remaining, $status, $invoiceId]);
            }
            
            $this->db->commit();
            return true;
        } catch (\Throwable $e) {
            if ($this->db->inTransaction()) $this->db->rollBack();
            error_log("AccountManager::recordPayment error: " . $e->getMessage());
            return false;
        }
    }
}
