<?php
if (!function_exists('audit_client_ip')) {
  function audit_client_ip(): string {
    $candidates = [
      $_SERVER['HTTP_CF_CONNECTING_IP'] ?? null,
      $_SERVER['HTTP_X_FORWARDED_FOR'] ?? null,
      $_SERVER['REMOTE_ADDR'] ?? null,
    ];
    foreach ($candidates as $value) {
      if (!$value) continue;
      $ip = trim(explode(',', (string)$value)[0]);
      if ($ip !== '') return substr($ip, 0, 64);
    }
    return '';
  }
}

if (!function_exists('ensure_audit_tables')) {
  function ensure_audit_tables(PDO $pdo): void {
    $pdo->exec("
      CREATE TABLE IF NOT EXISTS audit_logs (
        id BIGINT AUTO_INCREMENT PRIMARY KEY,
        company_id INT NULL,
        user_id INT NULL,
        module VARCHAR(100) NOT NULL,
        action VARCHAR(100) NOT NULL,
        entity_type VARCHAR(100) NULL,
        entity_id VARCHAR(100) NULL,
        description VARCHAR(255) NULL,
        ip_address VARCHAR(64) NULL,
        page_path VARCHAR(255) NULL,
        created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_audit_company (company_id),
        INDEX idx_audit_user (user_id),
        INDEX idx_audit_module (module),
        INDEX idx_audit_created_at (created_at)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    ");
  }
}

if (!function_exists('audit_log')) {
  function audit_log(PDO $pdo, array $data = []): void {
    try {
      ensure_audit_tables($pdo);
      $companyId   = array_key_exists('company_id', $data) ? $data['company_id'] : ($_SESSION['company_id'] ?? null);
      $userId      = array_key_exists('user_id', $data) ? $data['user_id'] : ($_SESSION['user_id'] ?? null);
      $module      = trim((string)($data['module'] ?? 'system'));
      $action      = trim((string)($data['action'] ?? 'UNKNOWN'));
      $entityType  = ($data['entity_type'] ?? null);
      $entityId    = ($data['entity_id'] ?? null);
      $description = ($data['description'] ?? null);
      $ipAddress   = substr((string)($data['ip_address'] ?? audit_client_ip()), 0, 64);
      $pagePath    = substr((string)($data['page_path'] ?? ($_SERVER['REQUEST_URI'] ?? '')), 0, 255);
      $st = $pdo->prepare("
        INSERT INTO audit_logs
          (company_id, user_id, module, action, entity_type, entity_id, description, ip_address, page_path)
        VALUES
          (?, ?, ?, ?, ?, ?, ?, ?, ?)
      ");
      $st->execute([
        $companyId !== '' ? $companyId : null,
        $userId !== '' ? $userId : null,
        $module !== '' ? $module : 'system',
        $action !== '' ? $action : 'UNKNOWN',
        $entityType !== '' ? $entityType : null,
        $entityId !== '' ? (string)$entityId : null,
        $description !== '' ? $description : null,
        $ipAddress !== '' ? $ipAddress : null,
        $pagePath !== '' ? $pagePath : null,
      ]);
    } catch (Throwable $e) {
      // Ignore audit logging failures.
    }
  }
}


if (!function_exists('audit_money')) {
  function audit_money($amount): string {
    return number_format((float)$amount, 2);
  }
}

if (!function_exists('audit_tx_type_label')) {
  function audit_tx_type_label(string $txType): string {
    return strtoupper(trim($txType)) === 'IN' ? 'وارد' : 'منصرف';
  }
}

if (!function_exists('audit_payment_method_label')) {
  function audit_payment_method_label(string $method): string {
    $m = strtoupper(trim($method));
    return match($m) {
      'BANK' => 'بنك',
      'CASH' => 'نقدي',
      default => ($method !== '' ? $method : '-'),
    };
  }
}

if (!function_exists('audit_account_label')) {
  function audit_account_label(PDO $pdo, int $companyId, ?int $accountId): string {
    $accountId = (int)$accountId;
    if ($accountId <= 0) return '-';
    try {
      $st = $pdo->prepare("SELECT code, name FROM accounts WHERE company_id=? AND id=? LIMIT 1");
      $st->execute([$companyId, $accountId]);
      $row = $st->fetch(PDO::FETCH_ASSOC);
      if (!$row) return '#' . $accountId;
      return trim(($row['code'] ?? '') . ' - ' . ($row['name'] ?? ''));
    } catch (Throwable $e) {
      return '#' . $accountId;
    }
  }
}

if (!function_exists('audit_compose_description')) {
  function audit_compose_description(string $title, array $pairs = []): string {
    $parts = [trim($title)];
    foreach ($pairs as $label => $value) {
      if ($value === null) continue;
      $value = trim((string)$value);
      if ($value === '') continue;
      $parts[] = trim((string)$label) . ': ' . $value;
    }
    $out = implode(' | ', $parts);
    return mb_substr($out, 0, 255, 'UTF-8');
  }
}

if (!function_exists('audit_cash_description')) {
  function audit_cash_description(PDO $pdo, int $companyId, string $title, array $data = []): string {
    return audit_compose_description($title, [
      'النوع' => audit_tx_type_label((string)($data['tx_type'] ?? '')),
      'المبلغ' => isset($data['amount']) ? audit_money($data['amount']) : null,
      'حساب النقدية' => audit_account_label($pdo, $companyId, (int)($data['cash_account_id'] ?? 0)),
      'الحساب المقابل' => audit_account_label($pdo, $companyId, (int)($data['counter_account_id'] ?? 0)),
      'البيان' => (string)($data['memo'] ?? ''),
      'التاريخ' => (string)($data['tx_date'] ?? ''),
    ]);
  }
}

