<?php
namespace App\Controllers;

require_once BASE_PATH . '/app/helpers/view_compat.php';
require_once BASE_PATH . '/app/helpers/permissions.php';

use App\Core\Database;

class AdminBrandingController
{
    private function startSession(): void
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }
    }

    protected function db()
    {
        return Database::getInstance();
    }

    private function role(): string
    {
        return (string)($_SESSION['role'] ?? $_SESSION['user_role'] ?? '');
    }

    private function requireAccess(): void
    {
        $this->startSession();

        if (empty($_SESSION['user_id'])) {
            header("Location: /easychair/login");
            exit;
        }

        if (!in_array($this->role(), [
            'super_admin','org_admin','admin',
            'conference_chair','organizer',
            'track_chair','section_editor'
        ], true)) {
            http_response_code(403);
            exit("Access denied.");
        }
    }

    /*
    --------------------------------------------------
    Resolve Conference Context
    --------------------------------------------------
    */

    private function currentConference(): ?array
    {
        $cid = (int)($_SESSION['conference_id'] ?? 0);

        if ($cid <= 0) return null;

        $stmt = $this->db()->prepare("
            SELECT * FROM conferences WHERE id=? LIMIT 1
        ");
        $stmt->execute([$cid]);

        $c = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$c) return null;

        if (
            $this->role() !== 'super_admin' &&
            (int)$c['org_id'] !== (int)($_SESSION['org_id'] ?? 0)
        ) {
            return null;
        }

        return $c;
    }

    /*
    --------------------------------------------------
    SAFE DIRECTORY CREATION (FIXED)
    --------------------------------------------------
    */

    private function ensureDirectory(string $dir): void
    {
        if (!is_dir($dir)) {

            if (!mkdir($dir, 0775, true) && !is_dir($dir)) {

                error_log("FAILED MKDIR: " . $dir);

                exit("Storage folder is not writable. Contact admin.");

            }
        }
    }

    /*
    --------------------------------------------------
    SAFE IMAGE UPLOAD (FIXED)
    --------------------------------------------------
    */

    private function saveImage(string $field, string $folder): ?string
    {
        if (
            empty($_FILES[$field]['name']) ||
            !is_uploaded_file($_FILES[$field]['tmp_name'])
        ) {
            return null;
        }

        $allowed = ['jpg','jpeg','png','webp','gif'];

        $ext = strtolower(pathinfo(
            $_FILES[$field]['name'],
            PATHINFO_EXTENSION
        ));

        $ext = preg_replace('/[^a-z0-9]/', '', $ext);

        if (!in_array($ext, $allowed, true)) {
            exit("Invalid image type.");
        }

        /*
        Base directory
        */

        $base =
            BASE_PATH . '/public/storage/branding';

        $this->ensureDirectory($base);

        /*
        Target directory
        */

        $dir = $base . '/' . $folder;

        $this->ensureDirectory($dir);

        /*
        Generate filename
        */

        $file = $field . '_' .
                date('YmdHis') . '_' .
                rand(1000,9999) . '.' . $ext;

        $target = $dir . '/' . $file;

        if (!move_uploaded_file(
            $_FILES[$field]['tmp_name'],
            $target
        )) {

            error_log("UPLOAD FAILED: " . $target);

            exit("Could not upload image.");
        }

        return 'branding/' . $folder . '/' . $file;
    }

    /*
    --------------------------------------------------
    Index
    --------------------------------------------------
    */

    public function index()
    {
        $this->requireAccess();

        $conference = $this->currentConference();
        $org = null;

        $orgId = (int)($_SESSION['org_id'] ?? 0);

        if ($conference) {
            $orgId = (int)$conference['org_id'];
        }

        if ($orgId > 0) {

            $stmt = $this->db()->prepare("
                SELECT * FROM organizations WHERE id=? LIMIT 1
            ");
            $stmt->execute([$orgId]);

            $org = $stmt->fetch(\PDO::FETCH_ASSOC);
        }

        ob_start();
        require BASE_PATH . '/app/views/admin/branding/index.php';
        $content = ob_get_clean();

        require BASE_PATH . '/app/views/layouts/admin_layout.php';
    }

    /*
    --------------------------------------------------
    Save Branding (FIXED)
    --------------------------------------------------
    */

    public function save()
    {
        $this->requireAccess();

        $conference = $this->currentConference();
        $orgId = (int)($_SESSION['org_id'] ?? 0);

        if ($conference) {
            $orgId = (int)$conference['org_id'];
        }

        if ($orgId <= 0) {
            exit("Organization context required.");
        }

        /*
        Organization branding
        */

        $orgLogo   = $this->saveImage('org_logo', 'org_' . $orgId);
        $orgBanner = $this->saveImage('org_banner', 'org_' . $orgId);

        if ($orgLogo || $orgBanner) {

            $sets = [];
            $params = [];

            if ($orgLogo) {
                $sets[] = "logo_path=?";
                $params[] = $orgLogo;
            }

            if ($orgBanner) {
                $sets[] = "banner_path=?";
                $params[] = $orgBanner;
            }

            $params[] = $orgId;

            $stmt = $this->db()->prepare("
                UPDATE organizations
                SET " . implode(',', $sets) . "
                WHERE id=?
            ");

            $stmt->execute($params);
        }

        /*
        Conference branding
        */

        if ($conference) {

            $cid = (int)$conference['id'];

            $confLogo   = $this->saveImage('conference_logo', 'conference_' . $cid);
            $confBanner = $this->saveImage('conference_banner', 'conference_' . $cid);

            if ($confLogo || $confBanner) {

                $sets = [];
                $params = [];

                if ($confLogo) {
                    $sets[] = "logo_path=?";
                    $params[] = $confLogo;
                }

                if ($confBanner) {
                    $sets[] = "banner_path=?";
                    $params[] = $confBanner;
                }

                $params[] = $cid;

                $stmt = $this->db()->prepare("
                    UPDATE conferences
                    SET " . implode(',', $sets) . "
                    WHERE id=?
                ");

                $stmt->execute($params);
            }
        }

        header("Location: /easychair/admin/branding?saved=1");
        exit;
    }
}
