<?php
/**
 * پورتال توسعه‌دهنده / پشتیبان‌گیری ACC
 * http://localhost/acc-engine/dev.php
 */
declare(strict_types=1);

define('ABSPATH', __DIR__ . '/');
define('ACC_PATH', __DIR__ . '/');
define('ACC_URL', '/acc-engine/');
define('ACC_BASE_PATH', __DIR__);

require __DIR__ . '/standalone/dev_bootstrap.php';

Acc_Dev_Portal::session_start();

$action = (string) ($_REQUEST['action'] ?? '');
$isAjax = (
    (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower((string) $_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest')
    || (isset($_SERVER['HTTP_ACCEPT']) && str_contains((string) $_SERVER['HTTP_ACCEPT'], 'application/json'))
    || ($action !== '' && $action !== 'download' && $_SERVER['REQUEST_METHOD'] === 'POST')
);

function acc_dev_json(array $payload, int $code = 200): void
{
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo wp_json_encode($payload, JSON_UNESCAPED_UNICODE);
    exit;
}

/* ── Download (auth + GET) ───────────────────────────── */
if ($action === 'download') {
    if (!Acc_Dev_Portal::require_auth()) {
        http_response_code(403);
        echo 'Forbidden';
        exit;
    }
    $id  = (int) ($_GET['id'] ?? 0);
    $row = Acc_Dev_Portal::get_backup($id);
    if (!$row) {
        http_response_code(404);
        echo 'Not found';
        exit;
    }
    $abs = Acc_Dev_Portal::root() . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $row['path']);
    $backupsRoot = realpath(Acc_Dev_Portal::root() . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'backups');
    $real = realpath($abs);
    if (!$real || !$backupsRoot || !str_starts_with($real, $backupsRoot) || !is_file($real)) {
        http_response_code(404);
        echo 'File missing';
        exit;
    }
    $mime = str_ends_with($real, '.gz') ? 'application/gzip' : 'application/octet-stream';
    header('Content-Type: ' . $mime);
    header('Content-Length: ' . filesize($real));
    header('Content-Disposition: attachment; filename="' . basename($real) . '"');
    header('X-Content-Type-Options: nosniff');
    readfile($real);
    exit;
}

/* ── POST API actions ────────────────────────────────── */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $action !== '') {
    if ($action === 'login') {
        if (!Acc_Dev_Portal::verify_csrf($_POST['csrf'] ?? '')) {
            acc_dev_json(['ok' => false, 'message' => 'CSRF نامعتبر'], 403);
        }
        $res = Acc_Dev_Portal::login((string) ($_POST['username'] ?? ''), (string) ($_POST['password'] ?? ''));
        acc_dev_json($res, $res['ok'] ? 200 : 401);
    }

    if ($action === 'logout') {
        Acc_Dev_Portal::logout();
        acc_dev_json(['ok' => true, 'message' => 'خروج انجام شد']);
    }

    if (!Acc_Dev_Portal::require_auth()) {
        acc_dev_json(['ok' => false, 'message' => 'نشست منقضی یا بدون دسترسی'], 401);
    }
    if (!Acc_Dev_Portal::verify_csrf($_POST['csrf'] ?? '')) {
        acc_dev_json(['ok' => false, 'message' => 'CSRF نامعتبر'], 403);
    }

    $uid = Acc_Dev_Portal::current_user_id();

    switch ($action) {
        case 'docs_sync':
            acc_dev_json(Acc_Dev_Portal::sync_handoff($uid));

        case 'docs_list':
            $doc = Acc_Dev_Portal::get_doc();
            if (!$doc) {
                acc_dev_json(['ok' => false, 'message' => 'سندی در DB نیست — نصب یا همگام‌سازی را اجرا کنید.']);
            }
            $sections = Acc_Dev_Portal::get_sections(
                (int) $doc['id'],
                (string) ($_POST['portal'] ?? 'all'),
                (string) ($_POST['q'] ?? '')
            );
            acc_dev_json(['ok' => true, 'doc' => $doc, 'sections' => $sections]);

        case 'assets_list':
            acc_dev_json([
                'ok'    => true,
                'items' => Acc_Dev_Portal::get_assets(
                    (string) ($_POST['portal'] ?? 'all'),
                    (string) ($_POST['kind'] ?? 'all')
                ),
            ]);

        case 'db_catalog_list':
            acc_dev_json(Acc_Dev_Portal::db_catalog_list([
                'prefix'   => (string) ($_POST['prefix'] ?? ''),
                'module'   => (string) ($_POST['module'] ?? ''),
                'q'        => (string) ($_POST['q'] ?? ''),
                'min_size' => (int) ($_POST['min_size'] ?? 0),
                'max_size' => (int) ($_POST['max_size'] ?? 0),
                'sort'     => (string) ($_POST['sort'] ?? 'name'),
            ]));

        case 'db_catalog_table':
            acc_dev_json(Acc_Dev_Portal::db_catalog_table(
                (string) ($_POST['table'] ?? ''),
                ($_POST['with_create'] ?? '1') === '1'
            ));

        case 'db_catalog_sample':
            acc_dev_json(Acc_Dev_Portal::db_catalog_sample(
                (string) ($_POST['table'] ?? ''),
                (int) ($_POST['limit'] ?? 20),
                ($_POST['exact_count'] ?? '0') === '1'
            ));

        case 'db_catalog_refresh_meta':
            acc_dev_json(Acc_Dev_Portal::db_catalog_refresh_meta());

        case 'code_catalog_list':
            acc_dev_json(Acc_Dev_Portal::code_catalog_list([
                'portal'         => (string) ($_POST['portal'] ?? 'all'),
                'kind'           => (string) ($_POST['kind'] ?? 'all'),
                'q'              => (string) ($_POST['q'] ?? ''),
                'sort'           => (string) ($_POST['sort'] ?? 'path'),
                'critical_only'  => ($_POST['critical_only'] ?? '0') === '1',
                'exclude_tiles'  => ($_POST['exclude_tiles'] ?? '0') === '1',
            ]));

        case 'code_catalog_scan':
            acc_dev_json(Acc_Dev_Portal::code_catalog_scan());

        case 'code_catalog_file':
            acc_dev_json(Acc_Dev_Portal::code_catalog_file((string) ($_POST['path'] ?? '')));

        case 'backup_code':
            acc_dev_json(Acc_Dev_Portal::create_code_backup([
                'include_fonts' => ($_POST['include_fonts'] ?? '1') === '1',
                'exclude_env'   => ($_POST['exclude_env'] ?? '1') === '1',
            ], $uid));

        case 'backup_db':
            $includeTables = (string) ($_POST['include_tables'] ?? '');
            acc_dev_json(Acc_Dev_Portal::create_db_backup([
                'exclude_gis'    => ($_POST['exclude_gis'] ?? '1') === '1',
                'include_gis'    => ($_POST['include_gis'] ?? '0') === '1',
                'include_tables' => $includeTables,
            ], $uid));

        case 'db_gis_tables':
            $items = Acc_Dev_Portal::list_gis_tables_with_sizes();
            $total = 0;
            foreach ($items as $row) {
                $total += (int) ($row['size_bytes'] ?? 0);
            }
            acc_dev_json([
                'ok'          => true,
                'items'       => $items,
                'total_bytes' => $total,
                'count'       => count($items),
            ]);

        case 'backups_list':
            $type = (string) ($_POST['type'] ?? '');
            acc_dev_json([
                'ok'    => true,
                'items' => Acc_Dev_Portal::list_backups($type !== '' ? $type : null),
            ]);

        case 'backup_delete':
            acc_dev_json(Acc_Dev_Portal::delete_backup((int) ($_POST['id'] ?? 0)));

        default:
            acc_dev_json(['ok' => false, 'message' => 'اکشن ناشناخته'], 400);
    }
}

/* ── HTML shell ──────────────────────────────────────── */
require ACC_PATH . 'templates/dev-page.php';
