<?php

declare(strict_types=1);

namespace App\Modules\Timeline;

use App\Core\BaseController;
use App\Core\Request;
use App\Core\Session;

/**
 * TimelineController — HTTP controller handler for the Couple Wedding Timeline Checklist.
 *
 * @package Inveetaire
 * @ref     RC-018
 */
class TimelineController extends BaseController
{
    protected string $layout = 'couple';
    private TimelineModel $model;

    private array $categories = [
        'Venue', 'Church', 'Tea Pai', 'Legal', 'Budget', 'Invitation', 
        'Guest', 'Decoration', 'Photography', 'Videography', 'Entertainment', 
        'Dress', 'Suit', 'Beauty', 'Transportation', 'Accommodation', 
        'Food', 'Cake', 'Souvenir', 'Music', 'Miscellaneous'
    ];

    private function getActiveCategories(): array
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        if ($workspaceId <= 0) {
            return $this->categories;
        }
        $budgetModel = new \App\Modules\Budget\BudgetModel();
        $cats = $budgetModel->getCategories($workspaceId);
        if (empty($cats)) {
            return $this->categories;
        }
        return array_column($cats, 'name');
    }

    public function __construct()
    {
        parent::__construct();
        $this->model = new TimelineModel();
    }

    /**
     * Display Timeline Dashboard.
     * Route: GET /app/couple/timeline
     */
    public function index(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        
        // Ensure default checklist is seeded
        $this->model->ensureDefaultChecklistExists($workspaceId);

        $stats = $this->model->getDashboardStats($workspaceId);
        $milestones = $this->model->getMilestones($workspaceId);
        $phases = $this->model->getPhases($workspaceId);

        $this->render('timeline/dashboard', [
            'title' => 'Timeline Planner',
            'stats' => $stats,
            'milestones' => $milestones,
            'phases' => $phases,
            'categories' => $this->getActiveCategories(),
            'success' => Session::get('success') ?? null,
            'error' => Session::get('error') ?? null
        ]);

        Session::set('success', null);
        Session::set('error', null);
    }

    /**
     * Display Tasks List View.
     * Route: GET /app/couple/timeline/tasks
     */
    public function tasks(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');

        $filters = [
            'phase_id' => $request->get('phase_id'),
            'category' => $request->get('category'),
            'status' => $request->get('status'),
            'priority' => $request->get('priority'),
            'search' => $request->get('search')
        ];

        $page = max(1, (int) $request->get('page', 1));
        $limit = 30;
        $offset = ($page - 1) * $limit;

        $tasks = $this->model->getTasks($workspaceId, $filters, $limit, $offset);
        $totalTasks = $this->model->getTasksCount($workspaceId, $filters);
        $totalPages = (int) ceil($totalTasks / $limit);

        $phases = $this->model->getPhases($workspaceId);

        $this->render('timeline/tasks', [
            'title' => 'Wedding Tasks Checklist',
            'tasks' => $tasks,
            'phases' => $phases,
            'categories' => $this->getActiveCategories(),
            'filters' => $filters,
            'page' => $page,
            'total_pages' => $totalPages,
            'total_tasks' => $totalTasks,
            'success' => Session::get('success') ?? null,
            'error' => Session::get('error') ?? null
        ]);

        Session::set('success', null);
        Session::set('error', null);
    }

    /**
     * Render Add Task form view.
     * Route: GET /app/couple/timeline/tasks/create
     */
    public function createTask(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $phases = $this->model->getPhases($workspaceId);

        $this->render('timeline/create_task', [
            'title' => 'Add Planning Task',
            'phases' => $phases,
            'categories' => $this->getActiveCategories(),
            'errors' => Session::get('errors') ?? [],
            'old' => Session::get('old_input') ?? []
        ]);

        Session::set('errors', null);
        Session::set('old_input', null);
    }

    /**
     * Store task item.
     * Route: POST /app/couple/timeline/tasks/create
     */
    public function storeTask(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $postData = $request->allPost();

        $errors = [];
        if (empty($postData['title'])) {
            $errors['title'] = 'Task title is required.';
        }
        if (empty($postData['phase_id'])) {
            $errors['phase_id'] = 'Planning phase is required.';
        }
        if (empty($postData['category'])) {
            $errors['category'] = 'Category is required.';
        }

        if (!empty($errors)) {
            Session::set('errors', $errors);
            Session::set('old_input', $postData);
            $this->flash('error', 'Please resolve the validation errors.');
            $this->redirect('/app/couple/timeline/tasks/create');
            return;
        }

        try {
            $this->model->createTask($workspaceId, $postData);
            $this->flash('success', 'Timeline planning task created successfully.');
            $this->redirect('/app/couple/timeline/tasks');
        } catch (\Throwable $e) {
            $this->flash('error', 'Failed to add task: ' . $e->getMessage());
            Session::set('old_input', $postData);
            $this->redirect('/app/couple/timeline/tasks/create');
        }
    }

    /**
     * Render Edit Task form.
     * Route: GET /app/couple/timeline/tasks/edit/{id}
     */
    public function editTask(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $id = (int) $request->param('id');

        $task = $this->model->getTask($workspaceId, $id);
        if (!$task) {
            $this->flash('error', 'Timeline task not found.');
            $this->redirect('/app/couple/timeline/tasks');
            return;
        }

        $phases = $this->model->getPhases($workspaceId);

        $this->render('timeline/edit_task', [
            'title' => 'Edit Planning Task',
            'task' => $task,
            'phases' => $phases,
            'categories' => $this->getActiveCategories(),
            'errors' => Session::get('errors') ?? [],
            'old' => Session::get('old_input') ?? []
        ]);

        Session::set('errors', null);
        Session::set('old_input', null);
    }

    /**
     * Process Task updates.
     * Route: POST /app/couple/timeline/tasks/edit/{id}
     */
    public function updateTask(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $id = (int) $request->param('id');
        $postData = $request->allPost();

        $errors = [];
        if (empty($postData['title'])) {
            $errors['title'] = 'Task title is required.';
        }
        if (empty($postData['phase_id'])) {
            $errors['phase_id'] = 'Planning phase is required.';
        }
        if (empty($postData['category'])) {
            $errors['category'] = 'Category is required.';
        }

        if (!empty($errors)) {
            Session::set('errors', $errors);
            Session::set('old_input', $postData);
            $this->flash('error', 'Please resolve the validation errors.');
            $this->redirect("/app/couple/timeline/tasks/edit/{$id}");
            return;
        }

        try {
            $this->model->updateTask($workspaceId, $id, $postData);
            $this->flash('success', 'Timeline planning task updated successfully.');
            $this->redirect('/app/couple/timeline/tasks');
        } catch (\Throwable $e) {
            $this->flash('error', 'Failed to update task: ' . $e->getMessage());
            Session::set('old_input', $postData);
            $this->redirect("/app/couple/timeline/tasks/edit/{$id}");
        }
    }

    /**
     * Delete Task.
     * Route: POST /app/couple/timeline/tasks/delete/{id}
     */
    public function deleteTask(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $id = (int) $request->param('id');

        try {
            $this->model->deleteTask($workspaceId, $id);
            $this->flash('success', 'Planning task deleted successfully.');
        } catch (\Throwable $e) {
            $this->flash('error', 'Failed to delete task: ' . $e->getMessage());
        }

        $this->redirect('/app/couple/timeline/tasks');
    }

    /**
     * Quick toggle completion.
     * Route: POST /app/couple/timeline/tasks/toggle-status/{id}
     */
    public function toggleStatus(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $id = (int) $request->param('id');

        try {
            $newStatus = $this->model->toggleStatus($workspaceId, $id);
            $this->flash('success', "Task status updated to {$newStatus}.");
        } catch (\Throwable $e) {
            $this->flash('error', 'Failed to toggle status: ' . $e->getMessage());
        }

        $referer = $_SERVER['HTTP_REFERER'] ?? '/app/couple/timeline/tasks';
        $this->redirect($referer);
    }

    // ─────────────────────────────────────────────────────────────────────────
    // CALENDAR VIEW
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Display Monthly Calendar View.
     * Route: GET /app/couple/timeline/calendar
     */
    public function calendar(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');

        $year = (int) $request->get('year', (int)date('Y'));
        $month = (int) $request->get('month', (int)date('n'));

        // Validate range to prevent overflow limits
        if ($month < 1) {
            $month = 12;
            $year--;
        } elseif ($month > 12) {
            $month = 1;
            $year++;
        }

        $tasks = $this->model->getCalendarTasks($workspaceId, $year, $month);
        
        // Group tasks by day
        $tasksByDay = [];
        foreach ($tasks as $t) {
            if (!empty($t['due_date'])) {
                $day = (int) date('j', strtotime($t['due_date']));
                $tasksByDay[$day][] = $t;
            }
        }

        $this->render('timeline/calendar', [
            'title' => 'Timeline Calendar',
            'year' => $year,
            'month' => $month,
            'tasks_by_day' => $tasksByDay,
            'success' => Session::get('success') ?? null,
            'error' => Session::get('error') ?? null
        ]);

        Session::set('success', null);
        Session::set('error', null);
    }

    // ─────────────────────────────────────────────────────────────────────────
    // MILESTONES CRUD HANDLERS
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Display milestones management page.
     * Route: GET /app/couple/timeline/milestones
     */
    public function milestones(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $milestones = $this->model->getMilestones($workspaceId);

        $this->render('timeline/milestones', [
            'title' => 'Milestones Management',
            'milestones' => $milestones,
            'success' => Session::get('success') ?? null,
            'error' => Session::get('error') ?? null
        ]);

        Session::set('success', null);
        Session::set('error', null);
    }

    /**
     * Create milestone.
     * Route: POST /app/couple/timeline/milestones/create
     */
    public function createMilestone(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $postData = $request->allPost();

        $title = trim((string) ($postData['title'] ?? ''));
        $targetDate = !empty($postData['target_date']) ? $postData['target_date'] : null;
        $notes = !empty($postData['notes']) ? trim($postData['notes']) : null;

        if ($title === '') {
            $this->flash('error', 'Milestone title cannot be empty.');
        } else {
            $this->model->createMilestone($workspaceId, $title, $targetDate, $notes);
            $this->flash('success', "Milestone '{$title}' added successfully.");
        }

        $this->redirect('/app/couple/timeline');
    }

    /**
     * Update milestone settings.
     * Route: POST /app/couple/timeline/milestones/edit/{id}
     */
    public function updateMilestone(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $id = (int) $request->param('id');
        $postData = $request->allPost();

        $title = trim((string) ($postData['title'] ?? ''));
        $targetDate = !empty($postData['target_date']) ? $postData['target_date'] : null;
        $isCompleted = (bool) ($postData['is_completed'] ?? false);
        $notes = !empty($postData['notes']) ? trim($postData['notes']) : null;

        if ($title === '') {
            $this->flash('error', 'Milestone title cannot be empty.');
        } else {
            $this->model->updateMilestone($workspaceId, $id, $title, $targetDate, $isCompleted, $notes);
            $this->flash('success', 'Milestone updated successfully.');
        }

        $this->redirect('/app/couple/timeline/milestones');
    }

    /**
     * Soft delete milestone.
     * Route: POST /app/couple/timeline/milestones/delete/{id}
     */
    public function deleteMilestone(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $id = (int) $request->param('id');

        try {
            $this->model->deleteMilestone($workspaceId, $id);
            $this->flash('success', 'Milestone deleted successfully.');
        } catch (\Throwable $e) {
            $this->flash('error', 'Failed to delete milestone: ' . $e->getMessage());
        }

        $this->redirect('/app/couple/timeline/milestones');
    }

    /**
     * Quick toggle completion.
     * Route: POST /app/couple/timeline/milestones/toggle-complete/{id}
     */
    public function toggleMilestoneComplete(Request $request): void
    {
        $workspaceId = (int) Session::get('active_workspace_id');
        $id = (int) $request->param('id');

        try {
            $this->model->toggleMilestoneComplete($workspaceId, $id);
            $this->flash('success', 'Milestone completion state toggled successfully.');
        } catch (\Throwable $e) {
            $this->flash('error', 'Failed to update milestone: ' . $e->getMessage());
        }

        $referer = $_SERVER['HTTP_REFERER'] ?? '/app/couple/timeline';
        $this->redirect($referer);
    }
}
