<?php

declare(strict_types=1);

namespace App\Services;

use PDO;

final class LabelDefinitionService
{
    private static ?array $cache = null;

    public function __construct(private PDO $pdo)
    {
    }

    public function tableReady(): bool
    {
        return table_exists($this->pdo, 'label_definitions');
    }

    public function ensureDefaults(): void
    {
        if (!$this->tableReady()) {
            return;
        }

        $st = $this->pdo->prepare("INSERT IGNORE INTO label_definitions (label_key, label_ar, category, description, is_active) VALUES (?, ?, ?, ?, 1)");
        foreach (self::defaults() as $row) {
            $st->execute([$row['label_key'], $row['label_ar'], $row['category'], $row['description'] ?? '']);
        }
        self::$cache = null;
    }

    public function grouped(): array
    {
        $defaults = self::defaults();
        $rows = [];
        if ($this->tableReady()) {
            $this->ensureDefaults();
            $rows = $this->pdo->query("SELECT * FROM label_definitions ORDER BY category, label_key")->fetchAll() ?: [];
        } else {
            $rows = $defaults;
        }

        $grouped = [];
        foreach ($rows as $row) {
            $category = (string)($row['category'] ?? 'general');
            $grouped[$category][] = $row;
        }
        return $grouped;
    }

    public function save(array $posted): void
    {
        if (!$this->tableReady()) {
            throw new \RuntimeException('مطلوب تشغيل ملف التحديث الخاص بتعريفات الاختصارات أولًا.');
        }
        $labels = is_array($posted['labels'] ?? null) ? $posted['labels'] : [];
        $st = $this->pdo->prepare("UPDATE label_definitions SET label_ar=?, is_active=?, updated_at=CURRENT_TIMESTAMP WHERE id=?");
        foreach ($labels as $id => $data) {
            $label = trim((string)($data['label_ar'] ?? ''));
            $active = !empty($data['is_active']) ? 1 : 0;
            if ($label === '') {
                continue;
            }
            $st->execute([$label, $active, (int)$id]);
        }

        $new = is_array($posted['new_label'] ?? null) ? $posted['new_label'] : [];
        $newKey = strtoupper(trim((string)($new['label_key'] ?? '')));
        $newLabel = trim((string)($new['label_ar'] ?? ''));
        $newCategory = trim((string)($new['category'] ?? 'statement_doc_type'));
        if ($newKey !== '' && $newLabel !== '') {
            $allowed = ['statement_doc_type','audit_action','audit_entity','meta'];
            if (!in_array($newCategory, $allowed, true)) {
                $newCategory = 'statement_doc_type';
            }
            $insert = $this->pdo->prepare("INSERT INTO label_definitions (label_key, label_ar, category, description, is_active) VALUES (?, ?, ?, ?, 1) ON DUPLICATE KEY UPDATE label_ar=VALUES(label_ar), is_active=1, updated_at=CURRENT_TIMESTAMP");
            $insert->execute([$newKey, $newLabel, $newCategory, 'تمت إضافته من شاشة تعريفات الاختصارات']);
        }
        self::$cache = null;
    }

    public static function translate(PDO $pdo, string $key, string $category = ''): string
    {
        $key = trim($key);
        if ($key === '') {
            return '';
        }

        if (self::$cache === null) {
            self::$cache = self::loadMap($pdo);
        }

        $catKey = $category !== '' ? $category . ':' . $key : '';
        if ($catKey !== '' && isset(self::$cache[$catKey])) {
            return self::$cache[$catKey];
        }
        if (isset(self::$cache['*:' . $key])) {
            return self::$cache['*:' . $key];
        }
        if (isset(self::$cache[$key])) {
            return self::$cache[$key];
        }

        return self::fallback($key);
    }

    public static function formatMeta(PDO $pdo, ?string $json): string
    {
        $json = trim((string)$json);
        if ($json === '') {
            return '';
        }
        $decoded = json_decode($json, true);
        if (!is_array($decoded)) {
            return $json;
        }
        $parts = [];
        foreach ($decoded as $key => $value) {
            if (is_array($value)) {
                $value = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            }
            $label = self::translate($pdo, (string)$key, 'meta');
            $parts[] = $label . ': ' . (string)$value;
        }
        return implode('، ', $parts);
    }

    private static function loadMap(PDO $pdo): array
    {
        $map = [];
        foreach (self::defaults() as $row) {
            $map[(string)$row['category'] . ':' . (string)$row['label_key']] = (string)$row['label_ar'];
            $map['*:' . (string)$row['label_key']] = (string)$row['label_ar'];
        }
        if (table_exists($pdo, 'label_definitions')) {
            $rows = $pdo->query("SELECT label_key, label_ar, category FROM label_definitions WHERE is_active=1")->fetchAll() ?: [];
            foreach ($rows as $row) {
                $key = (string)($row['label_key'] ?? '');
                $category = (string)($row['category'] ?? 'general');
                $label = trim((string)($row['label_ar'] ?? ''));
                if ($key !== '' && $label !== '') {
                    $map[$category . ':' . $key] = $label;
                    $map['*:' . $key] = $label;
                }
            }
        }
        return $map;
    }

    private static function fallback(string $key): string
    {
        $clean = str_replace(['_', '-'], ' ', $key);
        return trim($clean) !== '' ? $clean : $key;
    }

    public static function defaults(): array
    {
        return [
            // Party statement document types
            ['category'=>'statement_doc_type','label_key'=>'OPENING_BALANCE','label_ar'=>'رصيد افتتاحي','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'SALES_INV','label_ar'=>'فاتورة مبيعات','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'SALES_RCPT','label_ar'=>'سند قبض مبيعات','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'SALES_RECEIPT','label_ar'=>'سند قبض مبيعات','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'CHECK_RECEIVE','label_ar'=>'استلام شيك','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'CHECK_RECV','label_ar'=>'استلام شيك','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'RCPT','label_ar'=>'سند قبض','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'SALES_RET','label_ar'=>'مرتجع بيع','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'PURCHASE_INV','label_ar'=>'فاتورة شراء','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'PURCHASE_PAY','label_ar'=>'سداد فاتورة شراء','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'PURCHASE_RET','label_ar'=>'مرتجع شراء','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'PAYMENT','label_ar'=>'سداد مورد','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'SUPPLIER_PAYMENT','label_ar'=>'سداد مورد','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'PAY','label_ar'=>'سند صرف','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'CASH_PAYMENT','label_ar'=>'سند صرف','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'BANK_TRX','label_ar'=>'حركة بنك','description'=>'نوع حركة كشف الحساب'],
            ['category'=>'statement_doc_type','label_key'=>'POS_SALES_INV','label_ar'=>'فاتورة نقطة بيع','description'=>'نوع حركة كشف الحساب'],

            // Audit actions
            ['category'=>'audit_action','label_key'=>'LOGIN_SUCCESS','label_ar'=>'تسجيل دخول ناجح','description'=>'عملية في سجلات النظام'],
            ['category'=>'audit_action','label_key'=>'LOGIN_FAIL','label_ar'=>'فشل تسجيل الدخول','description'=>'عملية في سجلات النظام'],
            ['category'=>'audit_action','label_key'=>'LOGOUT','label_ar'=>'تسجيل خروج','description'=>'عملية في سجلات النظام'],
            ['category'=>'audit_action','label_key'=>'POST_POS_SALES_INV','label_ar'=>'ترحيل فاتورة نقطة بيع','description'=>'عملية في سجلات النظام'],
            ['category'=>'audit_action','label_key'=>'POST_SALES_INV','label_ar'=>'ترحيل فاتورة مبيعات','description'=>'عملية في سجلات النظام'],
            ['category'=>'audit_action','label_key'=>'POST_PURCHASE_INV','label_ar'=>'ترحيل فاتورة شراء','description'=>'عملية في سجلات النظام'],
            ['category'=>'audit_action','label_key'=>'CREATE','label_ar'=>'إضافة','description'=>'عملية في سجلات النظام'],
            ['category'=>'audit_action','label_key'=>'UPDATE','label_ar'=>'تعديل','description'=>'عملية في سجلات النظام'],
            ['category'=>'audit_action','label_key'=>'DELETE','label_ar'=>'حذف','description'=>'عملية في سجلات النظام'],
            ['category'=>'audit_action','label_key'=>'CANCEL','label_ar'=>'إلغاء','description'=>'عملية في سجلات النظام'],
            ['category'=>'audit_action','label_key'=>'POST','label_ar'=>'ترحيل','description'=>'عملية في سجلات النظام'],

            // Audit entities
            ['category'=>'audit_entity','label_key'=>'users','label_ar'=>'المستخدمون','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'sales_invoices','label_ar'=>'فواتير المبيعات','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'purchase_invoices','label_ar'=>'فواتير الشراء','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'sales_returns','label_ar'=>'مرتجعات البيع','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'purchase_returns','label_ar'=>'مرتجعات الشراء','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'customer_receipts','label_ar'=>'سندات القبض','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'cash_payments','label_ar'=>'سندات الصرف','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'supplier_payments','label_ar'=>'مدفوعات الموردين','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'party_ledger','label_ar'=>'دفتر حسابات الأطراف','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'bank_transactions','label_ar'=>'حركات البنوك','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'cashbox_transactions','label_ar'=>'حركات الخزن','description'=>'كيان في سجلات النظام'],
            ['category'=>'audit_entity','label_key'=>'stock_vouchers','label_ar'=>'أذون المخزون','description'=>'كيان في سجلات النظام'],

            // Meta keys
            ['category'=>'meta','label_key'=>'username','label_ar'=>'اسم المستخدم','description'=>'تفاصيل سجل النظام'],
            ['category'=>'meta','label_key'=>'ip','label_ar'=>'عنوان IP','description'=>'تفاصيل سجل النظام'],
            ['category'=>'meta','label_key'=>'total','label_ar'=>'الإجمالي','description'=>'تفاصيل سجل النظام'],
            ['category'=>'meta','label_key'=>'paid_amount','label_ar'=>'المدفوع','description'=>'تفاصيل سجل النظام'],
            ['category'=>'meta','label_key'=>'due_amount','label_ar'=>'المتبقي','description'=>'تفاصيل سجل النظام'],
            ['category'=>'meta','label_key'=>'cashbox_id','label_ar'=>'الخزنة','description'=>'تفاصيل سجل النظام'],
            ['category'=>'meta','label_key'=>'payment_method','label_ar'=>'طريقة الدفع','description'=>'تفاصيل سجل النظام'],
        ];
    }
}
