<?php

namespace Admin\Controllers;

use Admin\Controllers\AdminController;

class AdminFranchisePlanController extends AdminController
{
    /**
     * List all franchise plans
     */
    public function index()
    {
        requireAdmin();

        $stmt = $this->db->prepare("SELECT * FROM franchise_plans ORDER BY sort_order ASC");
        $stmt->execute();
        $plans = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        return $this->adminView('franchise-plans/index', [
            'plans' => $plans
        ]);
    }

    /**
     * Show create form
     */
    public function create()
    {
        requireAdmin();

        // Fetch courses for feature selection
        $stmt = $this->db->prepare("SELECT id, name FROM courses WHERE is_active = 1 ORDER BY name ASC");
        $stmt->execute();
        $courses = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        // Fetch existing plans for reference
        $stmt = $this->db->prepare("SELECT id, name, sort_order FROM franchise_plans ORDER BY sort_order ASC");
        $stmt->execute();
        $existingPlans = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        return $this->adminView('franchise-plans/create', [
            'courses'       => $courses,
            'existingPlans' => $existingPlans
        ]);
    }

    /**
     * Insert a new franchise plan
     */
    public function store()
    {
        requireAdmin();

        $this->validateCsrf();

        $name           = sanitize($_POST['name'] ?? '');
        $price          = (float) ($_POST['price'] ?? 0);
        $durationMonths = (int) ($_POST['duration_months'] ?? 0);
        $maxStudents    = (int) ($_POST['max_students'] ?? 0);
        $maxExams       = (int) ($_POST['max_exams'] ?? 0);
        $isActive       = isset($_POST['is_active']) ? 1 : 0;
        $sortOrder      = (int) ($_POST['sort_order'] ?? 0);

        // Build features JSON from posted data
        $features = [];
        $featureNames  = $_POST['feature_name'] ?? [];
        $featureValues = $_POST['feature_value'] ?? [];

        if (is_array($featureNames)) {
            for ($i = 0; $i < count($featureNames); $i++) {
                $fName  = sanitize($featureNames[$i] ?? '');
                $fValue = sanitize($featureValues[$i] ?? '');
                if ($fName !== '') {
                    $features[] = [
                        'name'  => $fName,
                        'value' => $fValue
                    ];
                }
            }
        }

        // Include selected course IDs in features if provided
        $selectedCourses = $_POST['course_ids'] ?? [];
        if (is_array($selectedCourses) && count($selectedCourses) > 0) {
            $features[] = [
                'name'  => 'included_courses',
                'value' => array_map('intval', $selectedCourses)
            ];
        }

        $featuresJson = json_encode($features);

        if ($name === '') {
            flash('error', 'Plan name is required.');
            redirect(BASE_PATH . '/admin/franchise-plans/create');
            return;
        }

        try {
            $stmt = $this->db->prepare("
                INSERT INTO franchise_plans (name, price, duration_months, features, max_students, max_exams, is_active, sort_order, created_at, updated_at)
                VALUES (:name, :price, :duration_months, :features, :max_students, :max_exams, :is_active, :sort_order, NOW(), NOW())
            ");
            $stmt->execute([
                'name'            => $name,
                'price'           => $price,
                'duration_months' => $durationMonths,
                'features'        => $featuresJson,
                'max_students'    => $maxStudents,
                'max_exams'       => $maxExams,
                'is_active'       => $isActive,
                'sort_order'      => $sortOrder
            ]);

            flash('success', 'Franchise plan created successfully.');
        } catch (\Exception $e) {
            flash('error', 'Failed to create plan: ' . $e->getMessage());
        }

        redirect(BASE_PATH . '/admin/franchise-plans');
    }

    /**
     * Show edit form
     */
    public function edit($params)
    {
        requireAdmin();

        $id = (int) ($params['id'] ?? 0);

        $stmt = $this->db->prepare("SELECT * FROM franchise_plans WHERE id = :id");
        $stmt->execute(['id' => $id]);
        $plan = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$plan) {
            flash('error', 'Plan not found.');
            redirect(BASE_PATH . '/admin/franchise-plans');
            return;
        }

        // Decode features JSON
        $plan['features_decoded'] = json_decode($plan['features'], true) ?? [];

        // Fetch courses for feature selection
        $stmt = $this->db->prepare("SELECT id, name FROM courses WHERE is_active = 1 ORDER BY name ASC");
        $stmt->execute();
        $courses = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        return $this->adminView('franchise-plans/edit', [
            'plan'    => $plan,
            'courses' => $courses
        ]);
    }

    /**
     * Update a franchise plan
     */
    public function update($params)
    {
        requireAdmin();

        $this->validateCsrf();

        $id = (int) ($params['id'] ?? 0);

        $stmt = $this->db->prepare("SELECT id FROM franchise_plans WHERE id = :id");
        $stmt->execute(['id' => $id]);
        if (!$stmt->fetch(\PDO::FETCH_ASSOC)) {
            flash('error', 'Plan not found.');
            redirect(BASE_PATH . '/admin/franchise-plans');
            return;
        }

        $name           = sanitize($_POST['name'] ?? '');
        $price          = (float) ($_POST['price'] ?? 0);
        $durationMonths = (int) ($_POST['duration_months'] ?? 0);
        $maxStudents    = (int) ($_POST['max_students'] ?? 0);
        $maxExams       = (int) ($_POST['max_exams'] ?? 0);
        $isActive       = isset($_POST['is_active']) ? 1 : 0;
        $sortOrder      = (int) ($_POST['sort_order'] ?? 0);

        // Build features JSON
        $features = [];
        $featureNames  = $_POST['feature_name'] ?? [];
        $featureValues = $_POST['feature_value'] ?? [];

        if (is_array($featureNames)) {
            for ($i = 0; $i < count($featureNames); $i++) {
                $fName  = sanitize($featureNames[$i] ?? '');
                $fValue = sanitize($featureValues[$i] ?? '');
                if ($fName !== '') {
                    $features[] = [
                        'name'  => $fName,
                        'value' => $fValue
                    ];
                }
            }
        }

        $selectedCourses = $_POST['course_ids'] ?? [];
        if (is_array($selectedCourses) && count($selectedCourses) > 0) {
            $features[] = [
                'name'  => 'included_courses',
                'value' => array_map('intval', $selectedCourses)
            ];
        }

        $featuresJson = json_encode($features);

        if ($name === '') {
            flash('error', 'Plan name is required.');
            redirect(BASE_PATH . '/admin/franchise-plans/edit/' . $id);
            return;
        }

        try {
            $stmt = $this->db->prepare("
                UPDATE franchise_plans
                SET name = :name, price = :price, duration_months = :duration_months,
                    features = :features, max_students = :max_students, max_exams = :max_exams,
                    is_active = :is_active, sort_order = :sort_order, updated_at = NOW()
                WHERE id = :id
            ");
            $stmt->execute([
                'name'            => $name,
                'price'           => $price,
                'duration_months' => $durationMonths,
                'features'        => $featuresJson,
                'max_students'    => $maxStudents,
                'max_exams'       => $maxExams,
                'is_active'       => $isActive,
                'sort_order'      => $sortOrder,
                'id'              => $id
            ]);

            flash('success', 'Franchise plan updated successfully.');
        } catch (\Exception $e) {
            flash('error', 'Failed to update plan: ' . $e->getMessage());
        }

        redirect(BASE_PATH . '/admin/franchise-plans');
    }

    /**
     * Delete a franchise plan
     */
    public function delete($params)
    {
        requireAdmin();

        $this->validateCsrf();

        $id = (int) ($params['id'] ?? 0);

        $stmt = $this->db->prepare("SELECT id FROM franchise_plans WHERE id = :id");
        $stmt->execute(['id' => $id]);
        if (!$stmt->fetch(\PDO::FETCH_ASSOC)) {
            flash('error', 'Plan not found.');
            redirect(BASE_PATH . '/admin/franchise-plans');
            return;
        }

        // Check if any applications reference this plan
        $stmt = $this->db->prepare("SELECT COUNT(*) AS cnt FROM branch_applications WHERE plan_id = :id");
        $stmt->execute(['id' => $id]);
        $count = $stmt->fetch(\PDO::FETCH_ASSOC);

        if ($count['cnt'] > 0) {
            flash('error', 'Cannot delete plan. There are ' . $count['cnt'] . ' application(s) linked to this plan.');
            redirect(BASE_PATH . '/admin/franchise-plans');
            return;
        }

        $stmt = $this->db->prepare("DELETE FROM franchise_plans WHERE id = :id");
        $stmt->execute(['id' => $id]);

        flash('success', 'Franchise plan deleted successfully.');
        redirect(BASE_PATH . '/admin/franchise-plans');
    }
}
