<?php

declare(strict_types=1);

namespace SuperAdmin\Controllers;

/**
 * Super Admin Certificate Template Controller
 *
 * Full CRUD for certificate/marksheet/affiliation/authorization templates.
 * Super Admin uploads a JPG background image and defines field positions
 * (student_name, father_name, roll_no, enrollment_no, course, duration,
 * grade, percentage, issue_date, qr_code, certificate_no, branch_name, etc.)
 *
 * Each field has: x_pos, y_pos, font_size, font_family, font_style,
 * font_color, align, width, is_qrcode, qr_size.
 *
 * Branches use these templates to generate certificates — they cannot
 * modify the template or field positions.
 */
class SuperAdminCertificateTemplateController extends SuperAdminBaseController
{
    /** Standard field keys available for all templates */
    private const FIELD_KEYS = [
        'student_name'   => 'Student Name',
        'father_name'    => 'Father Name',
        'mother_name'    => 'Mother Name',
        'roll_no'        => 'Roll No',
        'enrollment_no'  => 'Enrollment No',
        'course'         => 'Course Name',
        'duration'       => 'Course Duration',
        'grade'          => 'Grade',
        'percentage'     => 'Percentage',
        'division'       => 'Division',
        'issue_date'     => 'Issue Date',
        'certificate_no' => 'Certificate No',
        'branch_name'    => 'Branch Name',
        'branch_code'    => 'Branch Code',
        'dob'            => 'Date of Birth',
        'admission_date' => 'Admission Date',
        'completion_date'=> 'Completion Date',
        'qr_code'        => 'QR Code (verification)',
        'photo'          => 'Student Photo',
        'signature'      => 'Signature',
        'director_sign'  => 'Director Signature',
        'branch_sign'    => 'Branch Head Signature',
        'institute_name' => 'Institute Name',
        'institute_logo' => 'Institute Logo',
    ];

    /**
     * List all templates.
     */
    public function index(): void
    {
        requireSuperAdmin();

        $typeFilter = trim($_GET['type'] ?? '');

        $sql = "SELECT t.*,
                    (SELECT COUNT(*) FROM `certificate_template_fields` f WHERE f.`template_id` = t.`id`) AS field_count,
                    c.`name` AS course_name
                FROM `certificate_templates` t
                LEFT JOIN `courses` c ON t.`course_id` = c.`id`
                WHERE 1=1";
        $params = [];

        if ($typeFilter !== '' && in_array($typeFilter, ['certificate','marksheet','affiliation','authorization','renewal','franchise_agreement','id_card','admit_card'], true)) {
            $sql .= " AND t.`type` = :type";
            $params[':type'] = $typeFilter;
        }
        $sql .= " ORDER BY t.`type` ASC, t.`created_at` DESC";

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $templates = $stmt->fetchAll() ?: [];

        $this->superAdminView('certificate_templates/index', [
            'title'       => 'Certificate & Document Templates',
            'currentPage' => 'certificate_templates',
            'templates'   => $templates,
            'typeFilter'  => $typeFilter,
            'fieldKeys'   => self::FIELD_KEYS,
        ]);
    }

    /**
     * Show create template form.
     */
    public function create(): void
    {
        requireSuperAdmin();

        $courses = [];
        try {
            $stmt = $this->db->query("SELECT `id`, `name`, `category` FROM `courses` WHERE `active` = 1 ORDER BY `name` ASC");
            $courses = $stmt->fetchAll() ?: [];
        } catch (\Throwable $e) {}

        $this->superAdminView('certificate_templates/create', [
            'title'    => 'Create Template',
            'currentPage' => 'certificate_templates',
            'courses'  => $courses,
            'fieldKeys'=> self::FIELD_KEYS,
        ]);
    }

    /**
     * Store a new template.
     */
    public function store(): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        $name        = trim($_POST['name'] ?? '');
        $type        = trim($_POST['type'] ?? 'certificate');
        $courseId    = (int) ($_POST['course_id'] ?? 0) ?: null;
        $width       = (int) ($_POST['template_width'] ?? 842);
        $height      = (int) ($_POST['template_height'] ?? 595);
        $description = trim($_POST['description'] ?? '');
        $isActive    = isset($_POST['is_active']) ? 1 : 0;

        if (empty($name)) {
            flash('error', 'Template name is required.');
            redirect(BASE_PATH . '/super-admin/certificate-templates/create');
        }

        if (!in_array($type, ['certificate','marksheet','affiliation','authorization','renewal','franchise_agreement','id_card','admit_card'], true)) {
            $type = 'certificate';
        }

        // Handle JPG upload
        $bgImage = $this->handleImageUpload('background_image', 'certificate_templates');
        if (!$bgImage) {
            flash('error', 'Please upload a JPG/PNG background image for the template.');
            redirect(BASE_PATH . '/super-admin/certificate-templates/create');
        }

        try {
            $stmt = $this->db->prepare(
                "INSERT INTO `certificate_templates`
                    (`name`, `type`, `course_id`, `template_html`, `background_image`,
                     `template_width`, `template_height`, `description`, `is_active`,
                     `created_at`, `updated_at`)
                 VALUES
                    (:name, :type, :course_id, '', :bg, :w, :h, :desc, :active, NOW(), NOW())"
            );
            $stmt->execute([
                ':name'      => $name,
                ':type'      => $type,
                ':course_id' => $courseId,
                ':bg'        => $bgImage,
                ':w'         => $width,
                ':h'         => $height,
                ':desc'      => $description ?: null,
                ':active'    => $isActive,
            ]);
            $templateId = (int) $this->db->lastInsertId();

            $this->auditLog('template_create', 'certificate_templates', $templateId, "Created {$type} template '{$name}'");
            flash('success', "Template '{$name}' created. Now add field positions.");
            redirect(BASE_PATH . '/super-admin/certificate-templates/' . $templateId);
        } catch (\Throwable $e) {
            error_log('Template store error: ' . $e->getMessage());
            flash('error', 'Failed to create template: ' . $e->getMessage());
            redirect(BASE_PATH . '/super-admin/certificate-templates/create');
        }
    }

    /**
     * Show template details + field position editor.
     */
    public function show(int $id): void
    {
        requireSuperAdmin();

        $stmt = $this->db->prepare(
            "SELECT t.*, c.`name` AS course_name
             FROM `certificate_templates` t
             LEFT JOIN `courses` c ON t.`course_id` = c.`id`
             WHERE t.`id` = :id LIMIT 1"
        );
        $stmt->execute([':id' => $id]);
        $template = $stmt->fetch() ?: null;

        if (!$template) {
            flash('error', 'Template not found.');
            redirect(BASE_PATH . '/super-admin/certificate-templates');
        }

        // Fetch field positions
        $stmt = $this->db->prepare(
            "SELECT * FROM `certificate_template_fields`
             WHERE `template_id` = :tid
             ORDER BY `sort_order` ASC, `id` ASC"
        );
        $stmt->execute([':tid' => $id]);
        $fields = $stmt->fetchAll() ?: [];

        $this->superAdminView('certificate_templates/show', [
            'title'    => 'Template: ' . ($template['name'] ?? ''),
            'currentPage' => 'certificate_templates',
            'template' => $template,
            'fields'   => $fields,
            'fieldKeys'=> self::FIELD_KEYS,
        ]);
    }

    /**
     * Show edit template form.
     */
    public function edit(int $id): void
    {
        requireSuperAdmin();

        $stmt = $this->db->prepare("SELECT * FROM `certificate_templates` WHERE `id` = :id LIMIT 1");
        $stmt->execute([':id' => $id]);
        $template = $stmt->fetch() ?: null;

        if (!$template) {
            flash('error', 'Template not found.');
            redirect(BASE_PATH . '/super-admin/certificate-templates');
        }

        $courses = [];
        try {
            $stmt = $this->db->query("SELECT `id`, `name` FROM `courses` WHERE `active` = 1 ORDER BY `name` ASC");
            $courses = $stmt->fetchAll() ?: [];
        } catch (\Throwable $e) {}

        $this->superAdminView('certificate_templates/edit', [
            'title'    => 'Edit Template: ' . ($template['name'] ?? ''),
            'currentPage' => 'certificate_templates',
            'template' => $template,
            'courses'  => $courses,
        ]);
    }

    /**
     * Update template (name, type, dimensions, etc. — NOT fields).
     */
    public function update(int $id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        $stmt = $this->db->prepare("SELECT * FROM `certificate_templates` WHERE `id` = :id LIMIT 1");
        $stmt->execute([':id' => $id]);
        $template = $stmt->fetch() ?: null;
        if (!$template) {
            flash('error', 'Template not found.');
            redirect(BASE_PATH . '/super-admin/certificate-templates');
        }

        $name        = trim($_POST['name'] ?? '');
        $type        = trim($_POST['type'] ?? $template['type']);
        $courseId    = (int) ($_POST['course_id'] ?? 0) ?: null;
        $width       = (int) ($_POST['template_width'] ?? $template['template_width']);
        $height      = (int) ($_POST['template_height'] ?? $template['template_height']);
        $description = trim($_POST['description'] ?? '');
        $isActive    = isset($_POST['is_active']) ? 1 : 0;

        if (empty($name)) {
            flash('error', 'Template name is required.');
            redirect(BASE_PATH . '/super-admin/certificate-templates/' . $id . '/edit');
        }

        $bgImage = $template['background_image'];
        $uploaded = $this->handleImageUpload('background_image', 'certificate_templates');
        if ($uploaded) {
            if ($bgImage) $this->deleteImageFile($bgImage);
            $bgImage = $uploaded;
        }

        try {
            $stmt = $this->db->prepare(
                "UPDATE `certificate_templates` SET
                    `name` = :name, `type` = :type, `course_id` = :course_id,
                    `background_image` = :bg, `template_width` = :w,
                    `template_height` = :h, `description` = :desc,
                    `is_active` = :active, `updated_at` = NOW()
                 WHERE `id` = :id"
            );
            $stmt->execute([
                ':name'      => $name,
                ':type'      => $type,
                ':course_id' => $courseId,
                ':bg'        => $bgImage,
                ':w'         => $width,
                ':h'         => $height,
                ':desc'      => $description ?: null,
                ':active'    => $isActive,
                ':id'        => $id,
            ]);

            $this->auditLog('template_update', 'certificate_templates', $id, "Updated template '{$name}'");
            flash('success', 'Template updated successfully.');
        } catch (\Throwable $e) {
            flash('error', 'Failed to update template: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/certificate-templates/' . $id);
    }

    /**
     * Delete a template + all its fields.
     */
    public function delete(int $id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        try {
            $stmt = $this->db->prepare("SELECT `background_image`, `name` FROM `certificate_templates` WHERE `id` = :id LIMIT 1");
            $stmt->execute([':id' => $id]);
            $template = $stmt->fetch() ?: null;
            if (!$template) {
                flash('error', 'Template not found.');
                redirect(BASE_PATH . '/super-admin/certificate-templates');
            }

            // Delete fields
            $this->db->prepare("DELETE FROM `certificate_template_fields` WHERE `template_id` = :tid")->execute([':tid' => $id]);
            // Delete template
            $this->db->prepare("DELETE FROM `certificate_templates` WHERE `id` = :id")->execute([':id' => $id]);
            // Delete JPG file
            if (!empty($template['background_image'])) {
                $this->deleteImageFile($template['background_image']);
            }

            $this->auditLog('template_delete', 'certificate_templates', $id, "Deleted template '{$template['name']}'");
            flash('success', 'Template deleted successfully.');
        } catch (\Throwable $e) {
            flash('error', 'Failed to delete template: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/certificate-templates');
    }

    // ════════════════════════════════════════════════════════════════════════
    // FIELD POSITION MANAGEMENT
    // ════════════════════════════════════════════════════════════════════════

    /**
     * Add a field position to a template.
     */
    public function addField(int $id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        $fieldKey   = trim($_POST['field_key'] ?? '');
        $fieldLabel = trim($_POST['field_label'] ?? '') ?: (self::FIELD_KEYS[$fieldKey] ?? $fieldKey);
        $xPos       = (float) ($_POST['x_pos'] ?? 0);
        $yPos       = (float) ($_POST['y_pos'] ?? 0);
        $fontSize   = (int) ($_POST['font_size'] ?? 12);
        $fontFamily = trim($_POST['font_family'] ?? 'Arial');
        $fontStyle  = trim($_POST['font_style'] ?? '');
        $fontColor  = trim($_POST['font_color'] ?? '#000000');
        $align      = trim($_POST['align'] ?? 'C');
        $width      = (int) ($_POST['width'] ?? 0) ?: null;
        $isQrcode   = isset($_POST['is_qrcode']) ? 1 : 0;
        $qrSize     = (int) ($_POST['qr_size'] ?? 50);
        $sortOrder  = (int) ($_POST['sort_order'] ?? 0);

        if (empty($fieldKey)) {
            flash('error', 'Field key is required.');
            redirect(BASE_PATH . '/super-admin/certificate-templates/' . $id);
        }

        if (!in_array($align, ['L','C','R'], true)) $align = 'C';
        if (!in_array($fontFamily, ['Arial','Helvetica','Times','Courier','Inter'], true)) $fontFamily = 'Arial';

        try {
            $stmt = $this->db->prepare(
                "INSERT INTO `certificate_template_fields`
                    (`template_id`, `field_key`, `field_label`, `x_pos`, `y_pos`,
                     `font_size`, `font_family`, `font_style`, `font_color`,
                     `align`, `width`, `is_qrcode`, `qr_size`, `sort_order`, `created_at`)
                 VALUES
                    (:tid, :fkey, :flabel, :x, :y, :fs, :ff, :fst, :fc, :align, :w, :qr, :qrs, :so, NOW())"
            );
            $stmt->execute([
                ':tid'    => $id,
                ':fkey'   => $fieldKey,
                ':flabel' => $fieldLabel,
                ':x'      => $xPos,
                ':y'      => $yPos,
                ':fs'     => $fontSize,
                ':ff'     => $fontFamily,
                ':fst'    => $fontStyle,
                ':fc'     => $fontColor,
                ':align'  => $align,
                ':w'      => $width,
                ':qr'     => $isQrcode,
                ':qrs'    => $qrSize,
                ':so'     => $sortOrder,
            ]);

            $this->auditLog('template_field_add', 'certificate_template_fields', (int) $this->db->lastInsertId(), "Added field '{$fieldKey}' to template #{$id}");
            flash('success', "Field '{$fieldLabel}' added at ({$xPos}, {$yPos}).");
        } catch (\Throwable $e) {
            flash('error', 'Failed to add field: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/certificate-templates/' . $id);
    }

    /**
     * Update a field position.
     */
    public function updateField(int $id, int $field_id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        $xPos       = (float) ($_POST['x_pos'] ?? 0);
        $yPos       = (float) ($_POST['y_pos'] ?? 0);
        $fontSize   = (int) ($_POST['font_size'] ?? 12);
        $fontFamily = trim($_POST['font_family'] ?? 'Arial');
        $fontStyle  = trim($_POST['font_style'] ?? '');
        $fontColor  = trim($_POST['font_color'] ?? '#000000');
        $align      = trim($_POST['align'] ?? 'C');
        $width      = (int) ($_POST['width'] ?? 0) ?: null;
        $qrSize     = (int) ($_POST['qr_size'] ?? 50);
        $sortOrder  = (int) ($_POST['sort_order'] ?? 0);

        if (!in_array($align, ['L','C','R'], true)) $align = 'C';

        try {
            $stmt = $this->db->prepare(
                "UPDATE `certificate_template_fields` SET
                    `x_pos` = :x, `y_pos` = :y, `font_size` = :fs,
                    `font_family` = :ff, `font_style` = :fst, `font_color` = :fc,
                    `align` = :align, `width` = :w, `qr_size` = :qrs,
                    `sort_order` = :so
                 WHERE `id` = :fid AND `template_id` = :tid"
            );
            $stmt->execute([
                ':x'     => $xPos, ':y' => $yPos, ':fs' => $fontSize,
                ':ff'    => $fontFamily, ':fst' => $fontStyle, ':fc' => $fontColor,
                ':align' => $align, ':w' => $width, ':qrs' => $qrSize,
                ':so'    => $sortOrder, ':fid' => $field_id, ':tid' => $id,
            ]);
            flash('success', 'Field position updated.');
        } catch (\Throwable $e) {
            flash('error', 'Failed to update field: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/certificate-templates/' . $id);
    }

    /**
     * Delete a field position.
     */
    public function deleteField(int $id, int $field_id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        try {
            $this->db->prepare(
                "DELETE FROM `certificate_template_fields` WHERE `id` = :fid AND `template_id` = :tid"
            )->execute([':fid' => $field_id, ':tid' => $id]);
            flash('success', 'Field removed from template.');
        } catch (\Throwable $e) {
            flash('error', 'Failed to delete field: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/certificate-templates/' . $id);
    }

    /**
     * Bulk update field positions (called via AJAX from drag-and-drop interface).
     *
     * Receives JSON array of {id, x_pos, y_pos, font_size, font_color, align}
     * for all fields on a template. Updates them all in one transaction.
     *
     * Returns JSON response.
     */
    public function bulkUpdateFields(int $id): void
    {
        requireSuperAdmin();

        // Skip standard validateCsrf() because AJAX sends JSON body,
        // not form-encoded POST. Instead verify CSRF from header or JSON body.
        $csrfHeader = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
        $rawInput = file_get_contents('php://input');
        $data = json_decode($rawInput, true);

        // Check CSRF from header OR from JSON body
        $csrfFromJson = $data['csrf_token'] ?? '';
        $sessionCsrf = $_SESSION['csrf_token'] ?? '';
        if ((!empty($csrfHeader) && hash_equals($sessionCsrf, $csrfHeader))
            || (!empty($csrfFromJson) && hash_equals($sessionCsrf, $csrfFromJson))) {
            // CSRF valid — proceed
        } else {
            $this->json(['success' => false, 'error' => 'CSRF token mismatch. Please refresh the page.']);
        }

        if (!$data || !isset($data['fields']) || !is_array($data['fields'])) {
            $this->json(['success' => false, 'error' => 'No field data received.']);
        }

        $updated = 0;
        $errors = [];

        try {
            $this->db->beginTransaction();

            foreach ($data['fields'] as $fieldData) {
                $field_id = (int) ($fieldData['id'] ?? 0);
                $xPos    = (float) ($fieldData['x_pos'] ?? 0);
                $yPos    = (float) ($fieldData['y_pos'] ?? 0);
                $fontSize = (int) ($fieldData['font_size'] ?? 12);
                $fontColor = trim($fieldData['font_color'] ?? '#000000');
                $align   = trim($fieldData['align'] ?? 'C');
                $qrSize  = (int) ($fieldData['qr_size'] ?? 50);

                if ($field_id <= 0) continue;
                if (!in_array($align, ['L', 'C', 'R'], true)) $align = 'C';

                $stmt = $this->db->prepare(
                    "UPDATE `certificate_template_fields` SET
                        `x_pos` = :x, `y_pos` = :y,
                        `font_size` = :fs, `font_color` = :fc,
                        `align` = :align, `qr_size` = :qrs
                     WHERE `id` = :fid AND `template_id` = :tid"
                );
                $stmt->execute([
                    ':x'      => $xPos,
                    ':y'      => $yPos,
                    ':fs'     => $fontSize,
                    ':fc'     => $fontColor,
                    ':align'  => $align,
                    ':qrs'    => $qrSize,
                    ':fid'    => $field_id,
                    ':tid'    => $id,
                ]);
                $updated++;
            }

            $this->db->commit();
            $this->auditLog('template_fields_bulk_update', 'certificate_template_fields', null, "Bulk updated {$updated} field positions on template #{$id}");

            $this->json(['success' => true, 'updated' => $updated]);
        } catch (\Throwable $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            error_log('Bulk field update error: ' . $e->getMessage());
            $this->json(['success' => false, 'error' => $e->getMessage()]);
        }
    }
}
