<?php
namespace App\Controllers;

use App\Core\Auth;
use App\Core\Controller;
use App\Core\Database;
use App\Core\Permissions;
use App\Core\Request;
use App\Core\Session;

class AdminController extends Controller
{
    public function __construct()
    {
        if (!Auth::isAny(['ADMIN'])) {
            http_response_code(403);
            echo '<!doctype html><body style="font-family:sans-serif;padding:40px"><h1>403</h1><p>Administrator access only.</p></body>';
            exit;
        }
    }

    public function index(): void
    {
        $this->render('admin/index', [
            'pageTitle' => 'Administration', 'pageSubtitle' => 'Categories, queues, SLA, templates, roles and masters',
            'counts' => [
                'customers' => Database::scalar('SELECT COUNT(*) FROM customers'),
                'agents' => Database::scalar('SELECT COUNT(*) FROM users'),
                'categories' => Database::scalar('SELECT COUNT(*) FROM categories'),
                'articles' => Database::scalar('SELECT COUNT(*) FROM kb_articles'),
                'quarantine' => Database::scalar("SELECT COUNT(*) FROM mail_quarantine WHERE status = 'pending'"),
            ],
        ], 'layout/app');
    }

    // ---- Categories ------------------------------------------------
    public function categories(): void
    {
        $categories = Database::all('SELECT c.*, p.name AS parent_name FROM categories c LEFT JOIN categories p ON p.id = c.parent_id ORDER BY c.parent_id IS NULL DESC, c.name');
        $this->render('admin/categories', ['pageTitle' => 'Categories & Sub-categories', 'categories' => $categories]);
    }

    public function storeCategory(): void
    {
        $this->requireCsrf();
        $id = Database::insert('categories', ['name' => trim((string)Request::post('name')), 'parent_id' => Request::post('parent_id') ?: null]);
        $this->logAdmin('created', 'category', $id, Request::post('name'));
        Session::flash('success', 'Category added.');
        $this->redirect('/admin/categories');
    }

    public function toggleCategory(string $id): void
    {
        $this->requireCsrf();
        $current = Database::scalar('SELECT is_active FROM categories WHERE id = :id', ['id' => $id]);
        Database::update('categories', ['is_active' => $current ? 0 : 1], 'id = :id', ['id' => $id]);
        $this->logAdmin('toggled', 'category', (int)$id);
        $this->redirect('/admin/categories');
    }

    public function updateCategory(string $id): void
    {
        $this->requireCsrf();
        $category = Database::one('SELECT * FROM categories WHERE id = :id', ['id' => $id]);
        if (!$category) { $this->notFound(); return; }

        $parentId = Request::post('parent_id') ?: null;
        if ($parentId !== null && (int)$parentId === (int)$id) {
            Session::flash('error', 'A category cannot be its own parent.');
            $this->redirect('/admin/categories');
            return;
        }

        Database::update('categories', [
            'name' => trim((string)Request::post('name')), 'parent_id' => $parentId,
        ], 'id = :id', ['id' => $id]);
        $this->logAdmin('updated', 'category', (int)$id, Request::post('name'));
        Session::flash('success', 'Category updated.');
        $this->redirect('/admin/categories');
    }

    public function deleteCategory(string $id): void
    {
        $this->requireCsrf();
        $usage = [
            'tickets (category)' => (int)Database::scalar('SELECT COUNT(*) FROM tickets WHERE category_id = :id', ['id' => $id]),
            'tickets (sub-category)' => (int)Database::scalar('SELECT COUNT(*) FROM tickets WHERE sub_category_id = :id', ['id' => $id]),
            'sub-categories' => (int)Database::scalar('SELECT COUNT(*) FROM categories WHERE parent_id = :id', ['id' => $id]),
            'canned responses' => (int)Database::scalar('SELECT COUNT(*) FROM canned_responses WHERE category_id = :id', ['id' => $id]),
            'routing rules' => (int)Database::scalar('SELECT COUNT(*) FROM queue_routing_rules WHERE category_id = :id', ['id' => $id]),
        ];
        $inUse = array_filter($usage, fn($c) => $c > 0);
        if (!empty($inUse)) {
            $parts = [];
            foreach ($inUse as $label => $count) { $parts[] = "{$count} {$label}"; }
            Session::flash('error', 'Cannot delete — this category is referenced by ' . implode(', ', $parts) . '. Deactivate it instead.');
            $this->redirect('/admin/categories');
            return;
        }

        $name = Database::scalar('SELECT name FROM categories WHERE id = :id', ['id' => $id]);
        Database::run('DELETE FROM categories WHERE id = :id', ['id' => $id]);
        $this->logAdmin('deleted', 'category', (int)$id, $name);
        Session::flash('success', 'Category deleted.');
        $this->redirect('/admin/categories');
    }

    // ---- Priorities (definitions editable, scale fixed at 4 per BRD) ----
    public function priorities(): void
    {
        $priorities = Database::all('SELECT * FROM priorities ORDER BY sort_order');
        $this->render('admin/priorities', ['pageTitle' => 'Priority & Severity', 'priorities' => $priorities]);
    }

    public function updatePriority(string $id): void
    {
        $this->requireCsrf();
        Database::update('priorities', [
            'name' => Request::post('name'), 'definition' => Request::post('definition'), 'color' => Request::post('color'),
        ], 'id = :id', ['id' => $id]);
        $this->logAdmin('updated', 'priority', (int)$id);
        Session::flash('success', 'Priority updated.');
        $this->redirect('/admin/priorities');
    }

    // ---- Queues & Teams ----------------------------------------------
    public function queues(): void
    {
        $queues = Database::all('SELECT q.*, t.name AS team_name FROM queues q LEFT JOIN teams t ON t.id = q.team_id ORDER BY q.name');
        $teams = Database::all('SELECT * FROM teams WHERE is_active = 1 ORDER BY name');
        $this->render('admin/queues', ['pageTitle' => 'Queues & Teams', 'queues' => $queues, 'teams' => $teams]);
    }

    public function storeQueue(): void
    {
        $this->requireCsrf();
        $id = Database::insert('queues', [
            'name' => trim((string)Request::post('name')), 'team_id' => Request::post('team_id') ?: null,
            'description' => Request::post('description'), 'auto_assign' => Request::post('auto_assign', 'none'),
        ]);
        $this->logAdmin('created', 'queue', $id, Request::post('name'));
        Session::flash('success', 'Queue created.');
        $this->redirect('/admin/queues');
    }

    public function teams(): void
    {
        $teams = Database::all('SELECT * FROM teams ORDER BY name');
        $members = Database::all('SELECT tm.*, t.name AS team_name, u.name AS user_name FROM team_members tm JOIN teams t ON t.id = tm.team_id JOIN users u ON u.id = tm.user_id ORDER BY t.name, u.name');
        $agents = Database::all("SELECT * FROM users WHERE is_active = 1 ORDER BY name");
        $this->render('admin/teams', ['pageTitle' => 'Teams', 'teams' => $teams, 'members' => $members, 'agents' => $agents]);
    }

    public function storeTeam(): void
    {
        $this->requireCsrf();
        $id = Database::insert('teams', ['name' => trim((string)Request::post('name')), 'description' => Request::post('description')]);
        $this->logAdmin('created', 'team', $id, Request::post('name'));
        Session::flash('success', 'Team created.');
        $this->redirect('/admin/teams');
    }

    public function addTeamMember(string $id): void
    {
        $this->requireCsrf();
        try {
            Database::insert('team_members', ['team_id' => $id, 'user_id' => Request::post('user_id'), 'skills' => Request::post('skills')]);
            Session::flash('success', 'Member added.');
        } catch (\Throwable $e) {
            Session::flash('error', 'That agent is already on this team.');
        }
        $this->redirect('/admin/teams');
    }

    // ---- Business calendar & holidays ---------------------------------
    public function calendar(): void
    {
        $calendars = Database::all('SELECT * FROM business_calendars ORDER BY name');
        $holidays = Database::all('SELECT h.*, c.name AS calendar_name FROM holidays h JOIN business_calendars c ON c.id = h.calendar_id ORDER BY h.holiday_date');
        $this->render('admin/calendar', ['pageTitle' => 'Business Calendar & Holidays', 'calendars' => $calendars, 'holidays' => $holidays]);
    }

    public function storeHoliday(): void
    {
        $this->requireCsrf();
        Database::insert('holidays', [
            'calendar_id' => Request::post('calendar_id'), 'holiday_date' => Request::post('holiday_date'), 'name' => Request::post('name'),
        ]);
        $this->logAdmin('created', 'holiday', null, Request::post('name'));
        Session::flash('success', 'Holiday added. Applies to new SLA calculations only.');
        $this->redirect('/admin/calendar');
    }

    // ---- Templates & canned responses ----------------------------------
    public function templates(): void
    {
        $templates = Database::all('SELECT * FROM notification_templates ORDER BY event_code, channel');
        $canned = Database::all(
            'SELECT cr.*, cat.name AS category_name FROM canned_responses cr
             LEFT JOIN categories cat ON cat.id = cr.category_id ORDER BY cr.title'
        );
        $categories = Database::all('SELECT * FROM categories WHERE is_active = 1 ORDER BY parent_id IS NULL DESC, name');
        $this->render('admin/templates', ['pageTitle' => 'Templates', 'templates' => $templates, 'canned' => $canned, 'categories' => $categories]);
    }

    public function updateTemplate(string $id): void
    {
        $this->requireCsrf();
        Database::update('notification_templates', [
            'subject' => Request::post('subject'), 'body' => Request::post('body'),
            'is_active' => Request::post('is_active') ? 1 : 0,
        ], 'id = :id', ['id' => $id]);
        $this->logAdmin('updated', 'notification_template', (int)$id);
        Session::flash('success', 'Template saved.');
        $this->redirect('/admin/templates');
    }

    public function storeCanned(): void
    {
        $this->requireCsrf();
        Database::insert('canned_responses', [
            'title' => trim((string)Request::post('title')), 'body' => (string)Request::post('body'),
            'category_id' => Request::post('category_id') ?: null, 'created_by' => Auth::id(),
        ]);
        Session::flash('success', 'Canned response added.');
        $this->redirect('/admin/templates');
    }

    public function updateCanned(string $id): void
    {
        $this->requireCsrf();
        $canned = Database::one('SELECT * FROM canned_responses WHERE id = :id', ['id' => $id]);
        if (!$canned) { $this->notFound(); return; }

        Database::update('canned_responses', [
            'title' => trim((string)Request::post('title')), 'body' => (string)Request::post('body'),
            'category_id' => Request::post('category_id') ?: null, 'is_active' => Request::post('is_active') ? 1 : 0,
        ], 'id = :id', ['id' => $id]);
        $this->logAdmin('updated', 'canned_response', (int)$id, Request::post('title'));
        Session::flash('success', 'Canned response saved.');
        $this->redirect('/admin/templates');
    }

    public function deleteCanned(string $id): void
    {
        $this->requireCsrf();
        $title = Database::scalar('SELECT title FROM canned_responses WHERE id = :id', ['id' => $id]);
        Database::run('DELETE FROM canned_responses WHERE id = :id', ['id' => $id]);
        $this->logAdmin('deleted', 'canned_response', (int)$id, $title);
        Session::flash('success', 'Canned response deleted.');
        $this->redirect('/admin/templates');
    }

    // ---- Users / agents --------------------------------------------
    public function users(): void
    {
        $users = Database::all('SELECT u.*, r.name AS role_name FROM users u JOIN roles r ON r.id = u.role_id ORDER BY u.name');
        $roles = Database::all('SELECT * FROM roles ORDER BY id');
        $this->render('admin/users', ['pageTitle' => 'Agents & Roles', 'users' => $users, 'roles' => $roles]);
    }

    public function storeUser(): void
    {
        $this->requireCsrf();
        Database::insert('users', [
            'name' => trim((string)Request::post('name')), 'email' => trim((string)Request::post('email')),
            'password_hash' => password_hash((string)Request::post('password', 'Passw0rd!'), PASSWORD_DEFAULT),
            'role_id' => Request::post('role_id'), 'employee_no' => Request::post('employee_no'),
        ]);
        $this->logAdmin('created', 'user', null, Request::post('email'));
        Session::flash('success', 'Agent account created.');
        $this->redirect('/admin/users');
    }

    public function toggleUser(string $id): void
    {
        $this->requireCsrf();
        $current = Database::scalar('SELECT is_active FROM users WHERE id = :id', ['id' => $id]);
        Database::update('users', ['is_active' => $current ? 0 : 1], 'id = :id', ['id' => $id]);
        $this->logAdmin('toggled', 'user', (int)$id);
        $this->redirect('/admin/users');
    }

    // ---- Roles & permissions ------------------------------------------
    public function permissions(): void
    {
        $roles = Database::all("SELECT * FROM roles WHERE code != 'ADMIN' ORDER BY id");
        $granted = Database::all('SELECT role_id, permission_key FROM role_permissions');
        $grantedSet = [];
        foreach ($granted as $g) { $grantedSet[$g['role_id'] . ':' . $g['permission_key']] = true; }

        $this->render('admin/permissions', [
            'pageTitle' => 'Roles & Permissions', 'pageSubtitle' => 'What each role is allowed to do',
            'roles' => $roles, 'permissions' => Permissions::all(), 'grantedSet' => $grantedSet,
        ]);
    }

    public function updatePermissions(): void
    {
        $this->requireCsrf();
        $roles = Database::all("SELECT id FROM roles WHERE code != 'ADMIN'");
        $submitted = (array)Request::post('grant', []); // grant[roleId][] = permission_key

        Database::beginTransaction();
        try {
            Database::run('DELETE FROM role_permissions');
            $count = 0;
            foreach ($roles as $role) {
                foreach ((array)($submitted[$role['id']] ?? []) as $key) {
                    if (!Permissions::isValid($key)) continue; // ignore anything not in the canonical list
                    Database::insert('role_permissions', ['role_id' => $role['id'], 'permission_key' => $key]);
                    $count++;
                }
            }
            Database::commit();
        } catch (\Throwable $e) {
            Database::rollBack();
            throw $e;
        }

        $this->logAdmin('updated', 'role_permissions', null, "{$count} grant(s) saved");
        Session::flash('success', 'Permissions saved.');
        $this->redirect('/admin/permissions');
    }

    // ---- Customers / contacts / contracts (ERP masters) -----------------
    public function customers(): void
    {
        $customers = Database::all(
            "SELECT c.*, (SELECT COUNT(*) FROM contacts x WHERE x.customer_id = c.id) AS contact_count,
                    (SELECT COUNT(*) FROM contracts x WHERE x.customer_id = c.id AND x.is_active=1) AS contract_count
             FROM customers c ORDER BY c.name"
        );
        $this->render('admin/customers', ['pageTitle' => 'Customers & Contracts', 'customers' => $customers]);
    }

    public function storeCustomer(): void
    {
        $this->requireCsrf();
        $id = Database::insert('customers', ['name' => trim((string)Request::post('name')), 'code' => Request::post('code'), 'industry' => Request::post('industry')]);
        $this->logAdmin('created', 'customer', $id, Request::post('name'));
        Session::flash('success', 'Customer created.');
        $this->redirect('/admin/customers/' . $id);
    }

    public function updateCustomer(string $id): void
    {
        $this->requireCsrf();
        $customer = Database::one('SELECT * FROM customers WHERE id = :id', ['id' => $id]);
        if (!$customer) { $this->notFound(); return; }

        Database::update('customers', [
            'name' => trim((string)Request::post('name')), 'code' => trim((string)Request::post('code')),
            'industry' => trim((string)Request::post('industry')),
        ], 'id = :id', ['id' => $id]);
        $this->logAdmin('updated', 'customer', (int)$id, Request::post('name'));
        Session::flash('success', 'Customer details saved.');
        $this->redirect('/admin/customers/' . $id);
    }

    public function toggleCustomer(string $id): void
    {
        $this->requireCsrf();
        $current = Database::scalar('SELECT is_active FROM customers WHERE id = :id', ['id' => $id]);
        Database::update('customers', ['is_active' => $current ? 0 : 1], 'id = :id', ['id' => $id]);
        $this->logAdmin('toggled', 'customer', (int)$id);
        Session::flash('success', $current ? 'Customer deactivated.' : 'Customer activated.');
        $this->redirect('/admin/customers/' . $id);
    }

    public function customerShow(string $id): void
    {
        $customer = Database::one('SELECT * FROM customers WHERE id = :id', ['id' => $id]);
        if (!$customer) { $this->notFound(); return; }
        $contacts = Database::all('SELECT * FROM contacts WHERE customer_id = :id ORDER BY is_primary DESC, name', ['id' => $id]);
        $contracts = Database::all('SELECT * FROM contracts WHERE customer_id = :id ORDER BY start_date DESC', ['id' => $id]);
        $products = Database::all('SELECT * FROM products WHERE is_active = 1 ORDER BY name');

        // Modules (products) currently assigned to each of this customer's contracts,
        // grouped so the view can pre-check the right boxes and show badges per contract.
        $rows = Database::all(
            'SELECT cp.contract_id, cp.product_id FROM contract_products cp
             JOIN contracts c ON c.id = cp.contract_id WHERE c.customer_id = :id', ['id' => $id]
        );
        $moduleIdsByContract = [];
        foreach ($rows as $r) { $moduleIdsByContract[$r['contract_id']][] = (int)$r['product_id']; }

        $this->render('admin/customer_show', compact('customer', 'contacts', 'contracts', 'products', 'moduleIdsByContract') + ['pageTitle' => $customer['name']]);
    }

    /** Assign one or more modules (products) to a contract — replaces the current set. */
    public function updateContractModules(string $id): void
    {
        $this->requireCsrf();
        $contract = Database::one('SELECT * FROM contracts WHERE id = :id', ['id' => $id]);
        if (!$contract) { $this->notFound(); return; }

        $productIds = array_unique(array_map('intval', (array)Request::post('product_ids', [])));

        Database::beginTransaction();
        try {
            Database::run('DELETE FROM contract_products WHERE contract_id = :c', ['c' => $id]);
            foreach ($productIds as $pid) {
                Database::insert('contract_products', ['contract_id' => $id, 'product_id' => $pid]);
            }
            Database::commit();
        } catch (\Throwable $e) {
            Database::rollBack();
            throw $e;
        }

        $this->logAdmin('updated', 'contract_modules', (int)$id, count($productIds) . ' module(s) assigned');
        Session::flash('success', count($productIds) === 1 ? '1 module assigned.' : count($productIds) . ' modules assigned.');
        $this->redirect('/admin/customers/' . $contract['customer_id']);
    }

    public function storeContact(string $id): void
    {
        $this->requireCsrf();
        Database::insert('contacts', [
            'customer_id' => $id, 'name' => Request::post('name'), 'email' => Request::post('email'),
            'phone' => Request::post('phone'), 'is_primary' => Request::post('is_primary') ? 1 : 0,
            'portal_access' => Request::post('portal_access') ? 1 : 0,
            'password_hash' => password_hash((string)Request::post('password', 'Passw0rd!'), PASSWORD_DEFAULT),
        ]);
        Session::flash('success', 'Contact added.');
        $this->redirect('/admin/customers/' . $id);
    }

    public function updateContact(string $id): void
    {
        $this->requireCsrf();
        $contact = Database::one('SELECT * FROM contacts WHERE id = :id', ['id' => $id]);
        if (!$contact) { $this->notFound(); return; }

        $data = [
            'name' => trim((string)Request::post('name')), 'email' => trim((string)Request::post('email')),
            'phone' => trim((string)Request::post('phone')), 'is_primary' => Request::post('is_primary') ? 1 : 0,
            'portal_access' => Request::post('portal_access') ? 1 : 0,
        ];
        $newPassword = trim((string)Request::post('password'));
        if ($newPassword !== '') {
            $data['password_hash'] = password_hash($newPassword, PASSWORD_DEFAULT);
        }

        Database::update('contacts', $data, 'id = :id', ['id' => $id]);
        $this->logAdmin('updated', 'contact', (int)$id, $data['name']);
        Session::flash('success', 'Contact updated.' . ($newPassword !== '' ? ' Password reset.' : ''));
        $this->redirect('/admin/customers/' . $contact['customer_id']);
    }

    public function storeContract(string $id): void
    {
        $this->requireCsrf();
        $contractNo = trim((string)Request::post('contract_no'));
        if ($contractNo === '') {
            $contractNo = $this->generateContractNo();
        }
        Database::insert('contracts', [
            'customer_id' => $id, 'contract_no' => $contractNo, 'tier' => Request::post('tier'),
            'support_hours_total' => Request::post('support_hours_total', 0), 'coverage_window' => Request::post('coverage_window', 'Business hours'),
            'start_date' => Request::post('start_date'), 'end_date' => Request::post('end_date'),
        ]);
        Session::flash('success', "Contract {$contractNo} added. Use \"Assign modules...\" below to cover the products it includes.");
        $this->redirect('/admin/customers/' . $id);
    }

    /** Format AMC-YYYY-NNNN, sequential within the calendar year — used when Contract no. is left blank. */
    private function generateContractNo(): string
    {
        $year = date('Y');
        $prefix = "AMC-{$year}-";
        $max = Database::scalar(
            'SELECT MAX(CAST(SUBSTRING(contract_no, 10) AS UNSIGNED)) FROM contracts WHERE contract_no LIKE :p',
            ['p' => $prefix . '%']
        );
        $next = ((int)$max) + 1;
        return $prefix . str_pad((string)$next, 4, '0', STR_PAD_LEFT);
    }

    public function products(): void
    {
        $products = Database::all('SELECT * FROM products ORDER BY name');
        $this->render('admin/products', ['pageTitle' => 'Products / Modules', 'products' => $products]);
    }

    public function storeProduct(): void
    {
        $this->requireCsrf();
        $id = Database::insert('products', ['name' => Request::post('name'), 'module' => Request::post('module')]);
        $this->logAdmin('created', 'product', $id, Request::post('name'));
        Session::flash('success', 'Product added.');
        $this->redirect('/admin/products');
    }

    public function updateProduct(string $id): void
    {
        $this->requireCsrf();
        Database::update('products', [
            'name' => trim((string)Request::post('name')), 'module' => trim((string)Request::post('module')),
        ], 'id = :id', ['id' => $id]);
        $this->logAdmin('updated', 'product', (int)$id);
        Session::flash('success', 'Product updated.');
        $this->redirect('/admin/products');
    }

    public function toggleProduct(string $id): void
    {
        $this->requireCsrf();
        $current = Database::scalar('SELECT is_active FROM products WHERE id = :id', ['id' => $id]);
        Database::update('products', ['is_active' => $current ? 0 : 1], 'id = :id', ['id' => $id]);
        $this->logAdmin('toggled', 'product', (int)$id);
        $this->redirect('/admin/products');
    }

    public function deleteProduct(string $id): void
    {
        $this->requireCsrf();
        $usage = [
            'tickets' => (int)Database::scalar('SELECT COUNT(*) FROM tickets WHERE product_id = :id', ['id' => $id]),
            'contracts' => (int)Database::scalar('SELECT COUNT(*) FROM contract_products WHERE product_id = :id', ['id' => $id]),
            'KB articles' => (int)Database::scalar('SELECT COUNT(*) FROM kb_articles WHERE product_id = :id', ['id' => $id]),
            'SLA policies' => (int)Database::scalar('SELECT COUNT(*) FROM sla_policies WHERE product_id = :id', ['id' => $id]),
        ];
        $inUse = array_filter($usage, fn($c) => $c > 0);
        if (!empty($inUse)) {
            $parts = [];
            foreach ($inUse as $label => $count) { $parts[] = "{$count} {$label}"; }
            Session::flash('error', 'Cannot delete — this product is referenced by ' . implode(', ', $parts) . '. Deactivate it instead.');
            $this->redirect('/admin/products');
            return;
        }

        $name = Database::scalar('SELECT name FROM products WHERE id = :id', ['id' => $id]);
        Database::run('DELETE FROM products WHERE id = :id', ['id' => $id]);
        $this->logAdmin('deleted', 'product', (int)$id, $name);
        Session::flash('success', 'Product deleted.');
        $this->redirect('/admin/products');
    }

    public function auditLog(): void
    {
        $logs = Database::all('SELECT a.*, u.name AS user_name FROM admin_audit_log a LEFT JOIN users u ON u.id = a.user_id ORDER BY a.created_at DESC LIMIT 300');
        $this->render('admin/audit_log', ['pageTitle' => 'Administrative Audit Log', 'logs' => $logs]);
    }

    public function quarantine(): void
    {
        $items = Database::all("SELECT * FROM mail_quarantine WHERE status = 'pending' ORDER BY created_at DESC");
        $this->render('admin/quarantine', ['pageTitle' => 'Mail Quarantine', 'items' => $items]);
    }

    private function logAdmin(string $action, string $entity, ?int $entityId = null, ?string $details = null): void
    {
        Database::insert('admin_audit_log', ['user_id' => Auth::id(), 'action' => $action, 'entity' => $entity, 'entity_id' => $entityId, 'details' => $details]);
    }
}
