<?php
declare(strict_types=1);

namespace App\Controllers;

require_once BASE_PATH . '/app/helpers/conference_scope.php';

use App\Core\Controller;
use App\Core\Database;

final class AdminHomepageBuilderController extends Controller
{
    private function uploadImage(string $field, int $conferenceId, string $prefix): ?string
    {
        if (empty($_FILES[$field]['tmp_name'])) return null;

        if (!is_uploaded_file((string)$_FILES[$field]['tmp_name'])) {
            throw new \RuntimeException("Upload not detected (is_uploaded_file failed)");
        }

        $orig = basename((string)($_FILES[$field]['name'] ?? ''));
        $ext = strtolower(pathinfo($orig, PATHINFO_EXTENSION));
        if (!in_array($ext, ['jpg','jpeg','png','webp'], true)) {
            throw new \RuntimeException("Image must be jpg/jpeg/png/webp");
        }

        $dir = BASE_PATH . '/storage/uploads/slides';
        if (!is_dir($dir)) @mkdir($dir, 0775, true);
        if (!is_writable($dir)) throw new \RuntimeException("Upload dir not writable: {$dir}");

        $new = $prefix . '_' . $conferenceId . '_' . time() . '_' . bin2hex(random_bytes(3)) . '.' . $ext;
        $dest = $dir . '/' . $new;

        if (!move_uploaded_file((string)$_FILES[$field]['tmp_name'], $dest)) {
            throw new \RuntimeException("move_uploaded_file failed");
        }

        @chmod($dest, 0664);
        return 'uploads/slides/' . $new; // served via /public/storage symlink
    }

    private function jsonOk(array $payload = []): void
    {
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['ok'=>true] + $payload, JSON_UNESCAPED_UNICODE);
        exit;
    }

    public function index(): void
    {
        require_permission('admin.access');
        $db = Database::getInstance();

        $confs = $db->query("SELECT id,title_en,title_ar,logo_path FROM conferences WHERE (is_active=1 OR is_active IS NULL) ORDER BY id DESC")->fetchAll();
        $conferenceId = (int)($_GET['conference_id'] ?? 0);
        if ($conferenceId <= 0) {
            $conferenceId = function_exists('current_conference_id') ? (int)\current_conference_id() : (int)($confs[0]['id'] ?? 0);
        }

        $slides = [];
        $blocks = [];

        if ($conferenceId > 0) {
            $st = $db->prepare("SELECT * FROM conference_blocks WHERE conference_id=:cid AND block_type='hero_slide' ORDER BY sort_order ASC, id DESC");
            $st->execute([':cid'=>$conferenceId]);
            $slides = $st->fetchAll();

            $bt = $db->prepare("SELECT * FROM conference_blocks WHERE conference_id=:cid AND block_type<>'hero_slide' ORDER BY sort_order ASC, id DESC");
            $bt->execute([':cid'=>$conferenceId]);
            $blocks = $bt->fetchAll();
        }

        $this->view('admin/homepage/index', [
            'conferences'=>$confs,
            'conference_id'=>$conferenceId,
            'slides'=>$slides,
            'blocks'=>$blocks
        ]);
    }

    public function slideSave(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) redirect('admin/homepage');
        csrf_check();

        $db = Database::getInstance();
        $id = (int)($_POST['id'] ?? 0);
        $conferenceId = (int)($_POST['conference_id'] ?? 0);

        $titleEn = trim((string)($_POST['title_en'] ?? ''));
        $titleAr = trim((string)($_POST['title_ar'] ?? ''));
        $bodyEn  = trim((string)($_POST['body_en'] ?? ''));
        $bodyAr  = trim((string)($_POST['body_ar'] ?? ''));
        $link    = trim((string)($_POST['link_url'] ?? ''));
        $sort    = (int)($_POST['sort_order'] ?? 0);
        $active  = isset($_POST['is_active']) ? 1 : 0;

        if ($conferenceId <= 0) { flash('danger', trans('required_fields')); redirect('admin/homepage'); }

        $imagePath = null;
        try { $imagePath = $this->uploadImage('image', $conferenceId, 'slide'); }
        catch (\Throwable $e) {
            if (!empty($_FILES['image']['tmp_name'])) { flash('danger', 'Slide upload: '.$e->getMessage()); redirect('admin/homepage?conference_id='.$conferenceId); }
        }

        if ($id > 0) {
            $sql = "UPDATE conference_blocks SET
                      title_en=:te,title_ar=:ta,body_en=:be,body_ar=:ba,link_url=:lu,sort_order=:so,is_active=:ac";
            $params = [':te'=>$titleEn?:null,':ta'=>$titleAr?:null,':be'=>$bodyEn?:null,':ba'=>$bodyAr?:null,':lu'=>$link?:null,':so'=>$sort,':ac'=>$active,':id'=>$id,':cid'=>$conferenceId];
            if ($imagePath) { $sql .= ", image_path=:ip"; $params[':ip']=$imagePath; }
            $sql .= " WHERE id=:id AND conference_id=:cid AND block_type='hero_slide'";
            $db->prepare($sql)->execute($params);
        } else {
            if (!$imagePath) { flash('danger', 'Image is required for new slide'); redirect('admin/homepage?conference_id='.$conferenceId); }
            $db->prepare("
              INSERT INTO conference_blocks (conference_id, block_type, block_key, title_en, title_ar, body_en, body_ar, image_path, link_url, sort_order, is_active)
              VALUES (:cid,'hero_slide',NULL,:te,:ta,:be,:ba,:ip,:lu,:so,:ac)
            ")->execute([
                ':cid'=>$conferenceId,':te'=>$titleEn?:null,':ta'=>$titleAr?:null,':be'=>$bodyEn?:null,':ba'=>$bodyAr?:null,
                ':ip'=>$imagePath,':lu'=>$link?:null,':so'=>$sort,':ac'=>$active
            ]);
        }

        flash('success', trans('save'));
        redirect('admin/homepage?conference_id='.$conferenceId);
    }

    public function slideDelete(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) redirect('admin/homepage');
        csrf_check();

        $db = Database::getInstance();
        $id = (int)($_POST['id'] ?? 0);
        $conferenceId = (int)($_POST['conference_id'] ?? 0);

        if ($id > 0) $db->prepare("DELETE FROM conference_blocks WHERE id=:id AND block_type='hero_slide'")->execute([':id'=>$id]);
        flash('success', trans('deleted'));
        redirect('admin/homepage?conference_id='.$conferenceId);
    }

    public function blockSave(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) redirect('admin/homepage');
        csrf_check();

        $db = Database::getInstance();
        $conferenceId = (int)($_POST['conference_id'] ?? 0);

        $blockKey  = trim((string)($_POST['block_key'] ?? ''));
        $blockType = trim((string)($_POST['block_type'] ?? 'section_html'));

        $titleEn = trim((string)($_POST['title_en'] ?? ''));
        $titleAr = trim((string)($_POST['title_ar'] ?? ''));
        $bodyEn  = trim((string)($_POST['body_en'] ?? ''));
        $bodyAr  = trim((string)($_POST['body_ar'] ?? ''));
        $link    = trim((string)($_POST['link_url'] ?? ''));
        $sort    = (int)($_POST['sort_order'] ?? 0);
        $active  = isset($_POST['is_active']) ? 1 : 0;

        if ($conferenceId<=0 || $blockKey==='') { flash('danger', trans('required_fields')); redirect('admin/homepage?conference_id='.$conferenceId); }

        $imagePath = null;
        try { $imagePath = $this->uploadImage('block_image', $conferenceId, 'block'); }
        catch (\Throwable $e) {
            if (!empty($_FILES['block_image']['tmp_name'])) { flash('danger', 'Block image upload: '.$e->getMessage()); redirect('admin/homepage?conference_id='.$conferenceId); }
        }

        // Upsert (requires uq_conf_blockkey index)
        $db->prepare("
          INSERT INTO conference_blocks (conference_id, block_type, block_key, title_en, title_ar, body_en, body_ar, image_path, link_url, sort_order, is_active)
          VALUES (:cid,:bt,:bk,:te,:ta,:be,:ba,:ip,:lu,:so,:ac)
          ON DUPLICATE KEY UPDATE
            block_type=VALUES(block_type),
            title_en=VALUES(title_en), title_ar=VALUES(title_ar),
            body_en=VALUES(body_en), body_ar=VALUES(body_ar),
            image_path=COALESCE(VALUES(image_path), image_path),
            link_url=VALUES(link_url),
            sort_order=VALUES(sort_order),
            is_active=VALUES(is_active)
        ")->execute([
            ':cid'=>$conferenceId, ':bt'=>$blockType ?: 'section_html', ':bk'=>$blockKey,
            ':te'=>$titleEn?:null, ':ta'=>$titleAr?:null,
            ':be'=>$bodyEn?:null, ':ba'=>$bodyAr?:null,
            ':ip'=>$imagePath, ':lu'=>$link?:null, ':so'=>$sort, ':ac'=>$active
        ]);

        flash('success', trans('save'));
        redirect('admin/homepage?conference_id='.$conferenceId);
    }

    public function blockDelete(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) redirect('admin/homepage');
        csrf_check();

        $db = Database::getInstance();
        $id = (int)($_POST['id'] ?? 0);
        $conferenceId = (int)($_POST['conference_id'] ?? 0);

        if ($id > 0) $db->prepare("DELETE FROM conference_blocks WHERE id=:id AND block_type<>'hero_slide'")->execute([':id'=>$id]);
        flash('success', trans('deleted'));
        redirect('admin/homepage?conference_id='.$conferenceId);
    }

    // ===== Pack 53: Reorder slides =====
    public function reorderSlides(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) { http_response_code(405); exit; }
        csrf_check();

        $db = Database::getInstance();
        $conferenceId = (int)($_POST['conference_id'] ?? 0);
        $ids = $_POST['ids'] ?? [];
        if (!is_array($ids)) $ids = [];

        $order = 10;
        foreach ($ids as $id) {
            $id = (int)$id;
            if ($id <= 0) continue;
            $db->prepare("UPDATE conference_blocks SET sort_order=:so WHERE id=:id AND conference_id=:cid AND block_type='hero_slide'")
               ->execute([':so'=>$order, ':id'=>$id, ':cid'=>$conferenceId]);
            $order += 10;
        }

        $this->jsonOk();
    }

    // ===== Pack 53: Reorder blocks (non slides) =====
    public function reorderBlocks(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) { http_response_code(405); exit; }
        csrf_check();

        $db = Database::getInstance();
        $conferenceId = (int)($_POST['conference_id'] ?? 0);
        $ids = $_POST['ids'] ?? [];
        if (!is_array($ids)) $ids = [];

        $order = 10;
        foreach ($ids as $id) {
            $id = (int)$id;
            if ($id <= 0) continue;
            $db->prepare("UPDATE conference_blocks SET sort_order=:so WHERE id=:id AND conference_id=:cid AND block_type<>'hero_slide'")
               ->execute([':so'=>$order, ':id'=>$id, ':cid'=>$conferenceId]);
            $order += 10;
        }

        $this->jsonOk();
    }

    // ===== Pack 53: Toggle is_active =====
    public function toggleActive(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) { http_response_code(405); exit; }
        csrf_check();

        $db = Database::getInstance();
        $id = (int)($_POST['id'] ?? 0);
        $conferenceId = (int)($_POST['conference_id'] ?? 0);

        $db->prepare("UPDATE conference_blocks SET is_active = 1 - is_active WHERE id=:id AND conference_id=:cid")
           ->execute([':id'=>$id, ':cid'=>$conferenceId]);

        $this->jsonOk();
    }

    // ===== Pack 53: Duplicate item (slide or block) =====
    public function duplicateItem(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) { http_response_code(405); exit; }
        csrf_check();

        $db = Database::getInstance();
        $id = (int)($_POST['id'] ?? 0);
        $conferenceId = (int)($_POST['conference_id'] ?? 0);

        $st = $db->prepare("SELECT * FROM conference_blocks WHERE id=:id AND conference_id=:cid LIMIT 1");
        $st->execute([':id'=>$id, ':cid'=>$conferenceId]);
        $row = $st->fetch();
        if (!$row) $this->jsonOk(['message'=>'not_found']);

        $blockType = (string)$row['block_type'];
        $blockKey  = (string)($row['block_key'] ?? '');
        if ($blockKey !== '') {
            $blockKey = $blockKey . '_copy_' . substr(bin2hex(random_bytes(2)), 0, 4);
        } else {
            $blockKey = null; // slides keep null
        }

        $db->prepare("
          INSERT INTO conference_blocks
            (conference_id, block_type, block_key, title_en, title_ar, body_en, body_ar, image_path, link_url, sort_order, is_active)
          VALUES
            (:cid, :bt, :bk, :te, :ta, :be, :ba, :ip, :lu, :so, :ac)
        ")->execute([
            ':cid'=>$conferenceId,
            ':bt'=>$blockType,
            ':bk'=>$blockKey,
            ':te'=>$row['title_en'] ?? null,
            ':ta'=>$row['title_ar'] ?? null,
            ':be'=>$row['body_en'] ?? null,
            ':ba'=>$row['body_ar'] ?? null,
            ':ip'=>$row['image_path'] ?? null,
            ':lu'=>$row['link_url'] ?? null,
            ':so'=>((int)($row['sort_order'] ?? 0)) + 5,
            ':ac'=>(int)($row['is_active'] ?? 1),
        ]);

        $this->jsonOk();
    }

    // ===== Pack 54: Get item JSON =====
    public function getItem(): void
    {
        require_permission('admin.access');
        $db = Database::getInstance();

        $id = (int)($_GET['id'] ?? 0);
        $cid = (int)($_GET['conference_id'] ?? 0);

        $st = $db->prepare("SELECT * FROM conference_blocks WHERE id=:id AND conference_id=:cid LIMIT 1");
        $st->execute([':id'=>$id, ':cid'=>$cid]);
        $row = $st->fetch();

        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['ok'=> (bool)$row, 'row'=>$row], JSON_UNESCAPED_UNICODE);
        exit;
    }

    // ===== Pack 54: Update item AJAX (slide/block) =====
    public function updateItem(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) { http_response_code(405); exit; }
        csrf_check();

        $db = Database::getInstance();
        $id = (int)($_POST['id'] ?? 0);
        $cid = (int)($_POST['conference_id'] ?? 0);
        if ($id<=0 || $cid<=0) { http_response_code(400); echo "bad"; exit; }

        $st = $db->prepare("SELECT * FROM conference_blocks WHERE id=:id AND conference_id=:cid LIMIT 1");
        $st->execute([':id'=>$id, ':cid'=>$cid]);
        $row = $st->fetch();
        if (!$row) { http_response_code(404); echo "not found"; exit; }

        $titleEn = trim((string)($_POST['title_en'] ?? ''));
        $titleAr = trim((string)($_POST['title_ar'] ?? ''));
        $bodyEn  = trim((string)($_POST['body_en'] ?? ''));
        $bodyAr  = trim((string)($_POST['body_ar'] ?? ''));
        $link    = trim((string)($_POST['link_url'] ?? ''));
        $sort    = (int)($_POST['sort_order'] ?? (int)($row['sort_order'] ?? 0));
        $active  = isset($_POST['is_active']) ? (int)$_POST['is_active'] : (int)($row['is_active'] ?? 1);

        $blockKey = null;
        if (!empty($row['block_type']) && (string)$row['block_type'] !== 'hero_slide') {
            $blockKey = trim((string)($_POST['block_key'] ?? (string)($row['block_key'] ?? '')));
            if ($blockKey === '') $blockKey = (string)($row['block_key'] ?? '');
        }

        // Optional image upload
        $imgField = ((string)$row['block_type'] === 'hero_slide') ? 'image' : 'block_image';
        $newImage = null;
        try {
            $newImage = $this->uploadImage($imgField, $cid, ((string)$row['block_type']==='hero_slide')?'slide':'block');
        } catch (\Throwable $e) {
            if (!empty($_FILES[$imgField]['tmp_name'])) {
                header('Content-Type: application/json; charset=utf-8');
                echo json_encode(['ok'=>false,'error'=>$e->getMessage()], JSON_UNESCAPED_UNICODE);
                exit;
            }
        }

        $sql = "UPDATE conference_blocks SET
                  title_en=:te, title_ar=:ta,
                  body_en=:be, body_ar=:ba,
                  link_url=:lu,
                  sort_order=:so,
                  is_active=:ac";
        $params = [
            ':te'=>$titleEn?:null, ':ta'=>$titleAr?:null,
            ':be'=>$bodyEn?:null, ':ba'=>$bodyAr?:null,
            ':lu'=>$link?:null,
            ':so'=>$sort,
            ':ac'=>$active,
            ':id'=>$id, ':cid'=>$cid
        ];

        if ($blockKey !== null) { $sql .= ", block_key=:bk"; $params[':bk']=$blockKey; }
        if ($newImage) { $sql .= ", image_path=:ip"; $params[':ip']=$newImage; }

        $sql .= " WHERE id=:id AND conference_id=:cid";
        $db->prepare($sql)->execute($params);

        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['ok'=>true,'image_path'=>$newImage], JSON_UNESCAPED_UNICODE);
        exit;
    }

    // ===== Pack 54: Bulk actions =====
    public function bulkAction(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) { http_response_code(405); exit; }
        csrf_check();

        $db = Database::getInstance();
        $cid = (int)($_POST['conference_id'] ?? 0);
        $action = trim((string)($_POST['action'] ?? ''));
        $ids = $_POST['ids'] ?? [];
        if (!is_array($ids)) $ids = [];
        $ids = array_values(array_filter(array_map('intval', $ids)));

        if ($cid<=0 || empty($ids)) {
            header('Content-Type: application/json; charset=utf-8');
            echo json_encode(['ok'=>false,'error'=>'missing'], JSON_UNESCAPED_UNICODE);
            exit;
        }

        $in = implode(',', array_fill(0, count($ids), '?'));

        if ($action === 'enable') {
            $q = $db->prepare("UPDATE conference_blocks SET is_active=1 WHERE conference_id=? AND id IN ($in)");
            $q->execute(array_merge([$cid], $ids));
        } elseif ($action === 'disable') {
            $q = $db->prepare("UPDATE conference_blocks SET is_active=0 WHERE conference_id=? AND id IN ($in)");
            $q->execute(array_merge([$cid], $ids));
        } else {
            header('Content-Type: application/json; charset=utf-8');
            echo json_encode(['ok'=>false,'error'=>'bad_action'], JSON_UNESCAPED_UNICODE);
            exit;
        }

        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['ok'=>true], JSON_UNESCAPED_UNICODE);
        exit;
    }



    // ===== Pack 58: Create new item AJAX =====
    public function createItemAjax(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) { http_response_code(405); exit; }
        csrf_check();

        $db = Database::getInstance();
        $cid = (int)($_POST['conference_id'] ?? 0);
        $blockType = trim((string)($_POST['block_type'] ?? 'section_html'));

        if ($cid<=0) {
            header('Content-Type: application/json; charset=utf-8');
            echo json_encode(['ok'=>false,'error'=>'conference_id required'], JSON_UNESCAPED_UNICODE);
            exit;
        }

        if (!in_array($blockType, ['hero_slide','panel','topic','section_html','important_date'], true)) {
            $blockType = 'section_html';
        }

        $blockKey = null;
        if ($blockType !== 'hero_slide') {
            $blockKey = trim((string)($_POST['block_key'] ?? ''));
            if ($blockKey === '') {
                header('Content-Type: application/json; charset=utf-8');
                echo json_encode(['ok'=>false,'error'=>'block_key required'], JSON_UNESCAPED_UNICODE);
                exit;
            }
        }

        $titleEn = trim((string)($_POST['title_en'] ?? ''));
        $titleAr = trim((string)($_POST['title_ar'] ?? ''));
        $bodyEn  = trim((string)($_POST['body_en'] ?? ''));
        $bodyAr  = trim((string)($_POST['body_ar'] ?? ''));
        $link    = trim((string)($_POST['link_url'] ?? ''));
        $sort    = (int)($_POST['sort_order'] ?? 0);
        $active  = isset($_POST['is_active']) ? (int)$_POST['is_active'] : 1;

        // Upload image optional (required for hero_slide create)
        $imgField = ($blockType === 'hero_slide') ? 'image' : 'block_image';
        $imagePath = null;
        try {
            $imagePath = $this->uploadImage($imgField, $cid, ($blockType==='hero_slide')?'slide':'block');
        } catch (\Throwable $e) {
            if (!empty($_FILES[$imgField]['tmp_name'])) {
                header('Content-Type: application/json; charset=utf-8');
                echo json_encode(['ok'=>false,'error'=>$e->getMessage()], JSON_UNESCAPED_UNICODE);
                exit;
            }
        }

        if ($blockType === 'hero_slide' && !$imagePath) {
            header('Content-Type: application/json; charset=utf-8');
            echo json_encode(['ok'=>false,'error'=>'image required for slide'], JSON_UNESCAPED_UNICODE);
            exit;
        }

        $db->prepare("
          INSERT INTO conference_blocks
            (conference_id, block_type, block_key, title_en, title_ar, body_en, body_ar, image_path, link_url, sort_order, is_active)
          VALUES
            (:cid, :bt, :bk, :te, :ta, :be, :ba, :ip, :lu, :so, :ac)
        ")->execute([
            ':cid'=>$cid,
            ':bt'=>$blockType,
            ':bk'=>$blockKey,
            ':te'=>$titleEn?:null,
            ':ta'=>$titleAr?:null,
            ':be'=>$bodyEn?:null,
            ':ba'=>$bodyAr?:null,
            ':ip'=>$imagePath,
            ':lu'=>$link?:null,
            ':so'=>$sort,
            ':ac'=>$active
        ]);

        $newId = (int)$db->query("SELECT LAST_INSERT_ID()")->fetchColumn();
        $st = $db->prepare("SELECT * FROM conference_blocks WHERE id=:id LIMIT 1");
        $st->execute([':id'=>$newId]);
        $row = $st->fetch();

        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['ok'=>true,'row'=>$row], JSON_UNESCAPED_UNICODE);
        exit;
    }


}
