<?php

namespace App\Controllers;

use App\Services\Database;

class TasksController extends BaseController
{
    protected $db;

    public function __construct()
    {
        parent::__construct();
        $this->db = Database::getInstance();
    }

    /**
     * Crear una nueva tarea
     */
    public function create()
    {
        header('Content-Type: application/json');
        
        try {
            $token = $_POST['csrf_token'] ?? '';
            $this->validateCsrfToken($token);

            $data = [
                'backlog_item_id' => $_POST['backlog_item_id'] ?? null,
                'title' => $_POST['title'] ?? null,
                'description' => $_POST['description'] ?? null,
                'status' => $_POST['status'] ?? 'todo',
                'estimated_hours' => $_POST['estimated_hours'] ?? null,
                'assigned_to' => !empty($_POST['assigned_to']) ? $_POST['assigned_to'] : null
            ];

            error_log("Creating task with data: " . json_encode($data));

            // Validaciones
            if (empty($data['backlog_item_id'])) {
                throw new \Exception('El ID del backlog item es requerido');
            }

            if (empty($data['title'])) {
                throw new \Exception('El título de la tarea es requerido');
            }

            // Verificar que el backlog item existe
            $item = $this->db->fetchOne(
                "SELECT id, project_id FROM product_backlog_items WHERE id = ?",
                [$data['backlog_item_id']]
            );

            if (!$item) {
                throw new \Exception('El backlog item no existe');
            }

            // Insertar tarea
            $sql = "INSERT INTO tasks 
                    (backlog_item_id, title, description, status, estimated_hours, assigned_to)
                    VALUES (?, ?, ?, ?, ?, ?)";

            $params = [
                $data['backlog_item_id'],
                $data['title'],
                $data['description'],
                $data['status'],
                $data['estimated_hours'],
                $data['assigned_to']
            ];

            $taskId = $this->db->insert($sql, $params);
            error_log("Task created with ID: $taskId");

            // Registrar en historial si es parte de un proyecto (opcional, no crítico)
            if (!empty($item['project_id'])) {
                try {
                    $this->db->query(
                        "INSERT INTO project_history (project_id, user_id, action, field_name, new_value)
                         VALUES (?, ?, ?, ?, ?)",
                        [
                            $item['project_id'],
                            $_SESSION['user']['id'],
                            'creó la tarea',
                            'task',
                            $data['title']
                        ]
                    );
                } catch (\Exception $e) {
                    error_log("Warning: Could not insert into project_history: " . $e->getMessage());
                    // Continuar sin error, el historial no es crítico
                }
            }

            echo json_encode([
                'success' => true,
                'message' => 'Tarea creada exitosamente',
                'task_id' => $taskId
            ]);

        } catch (\Exception $e) {
            error_log("Error creating task: " . $e->getMessage());
            http_response_code(400);
            echo json_encode([
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Actualizar una tarea
     */
    public function update($id)
    {
        header('Content-Type: application/json');
        
        try {
            $token = $_POST['csrf_token'] ?? '';
            $this->validateCsrfToken($token);

            $action = $_POST['action'] ?? 'update_full';

            switch ($action) {
                case 'update_status':
                    $this->updateStatus($id);
                    break;

                case 'update_hours':
                    $this->updateHours($id);
                    break;

                case 'update_full':
                    $this->updateFull($id);
                    break;

                default:
                    throw new \Exception('Acción no válida');
            }

        } catch (\Exception $e) {
            error_log("Error updating task: " . $e->getMessage());
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
            exit;
        }
    }

    /**
     * Actualizar solo el estado de la tarea
     */
    private function updateStatus($id)
    {
        $status = $_POST['status'] ?? null;

        if (!in_array($status, ['todo', 'in_progress', 'done'])) {
            throw new \Exception('Estado no válido');
        }

        // Obtener tarea actual
        $task = $this->db->fetchOne(
            "SELECT t.*, pbi.project_id 
             FROM tasks t
             JOIN product_backlog_items pbi ON t.backlog_item_id = pbi.id
             WHERE t.id = ?",
            [$id]
        );

        if (!$task) {
            throw new \Exception('Tarea no encontrada');
        }

        // Si se marca como "done", registrar horas estimadas si no hay reales
        $actualHours = $task['actual_hours'];
        if ($status === 'done' && empty($actualHours) && !empty($task['estimated_hours'])) {
            $actualHours = $task['estimated_hours'];
        }

        $this->db->query(
            "UPDATE tasks SET status = ?, actual_hours = ? WHERE id = ?",
            [$status, $actualHours, $id]
        );

        // Actualizar horas totales del backlog item
        $this->updateBacklogItemHours($task['backlog_item_id']);

        // Si hay proyecto, actualizar progreso
        if ($task['project_id']) {
            $this->updateProjectProgress($task['project_id']);
        }

        echo json_encode(['success' => true, 'message' => 'Estado actualizado']);
        exit;
    }

    /**
     * Actualizar horas de la tarea
     */
    private function updateHours($id)
    {
        $actualHours = $_POST['actual_hours'] ?? null;

        if ($actualHours !== null && (!is_numeric($actualHours) || $actualHours < 0)) {
            throw new \Exception('Las horas deben ser un número positivo');
        }

        // Obtener tarea
        $task = $this->db->fetchOne(
            "SELECT t.*, pbi.project_id 
             FROM tasks t
             JOIN product_backlog_items pbi ON t.backlog_item_id = pbi.id
             WHERE t.id = ?",
            [$id]
        );

        if (!$task) {
            throw new \Exception('Tarea no encontrada');
        }

        $this->db->query(
            "UPDATE tasks SET actual_hours = ? WHERE id = ?",
            [$actualHours, $id]
        );

        // Actualizar horas totales del backlog item
        $this->updateBacklogItemHours($task['backlog_item_id']);

        echo json_encode(['success' => true, 'message' => 'Horas actualizadas']);
        exit;
    }

    /**
     * Actualizar todos los campos de la tarea
     */
    private function updateFull($id)
    {
        $data = [
            'title' => $_POST['title'] ?? null,
            'description' => $_POST['description'] ?? null,
            'status' => $_POST['status'] ?? 'todo',
            'estimated_hours' => $_POST['estimated_hours'] ?? null,
            'actual_hours' => $_POST['actual_hours'] ?? null,
            'assigned_to' => $_POST['assigned_to'] ?? null
        ];

        if (empty($data['title'])) {
            throw new \Exception('El título es requerido');
        }

        // Obtener tarea
        $task = $this->db->fetchOne(
            "SELECT t.*, pbi.project_id 
             FROM tasks t
             JOIN product_backlog_items pbi ON t.backlog_item_id = pbi.id
             WHERE t.id = ?",
            [$id]
        );

        if (!$task) {
            throw new \Exception('Tarea no encontrada');
        }

        $this->db->query(
            "UPDATE tasks 
             SET title = ?, description = ?, status = ?, 
                 estimated_hours = ?, actual_hours = ?, assigned_to = ?
             WHERE id = ?",
            [
                $data['title'],
                $data['description'],
                $data['status'],
                $data['estimated_hours'],
                $data['actual_hours'],
                $data['assigned_to'],
                $id
            ]
        );

        // Actualizar horas totales del backlog item
        $this->updateBacklogItemHours($task['backlog_item_id']);

        // Si hay proyecto, actualizar progreso
        if ($task['project_id']) {
            $this->updateProjectProgress($task['project_id']);
        }

        echo json_encode(['success' => true, 'message' => 'Tarea actualizada exitosamente']);
        exit;
    }

    /**
     * Eliminar una tarea
     */
    public function delete($id)
    {
        header('Content-Type: application/json');
        
        try {
            $token = $_POST['csrf_token'] ?? '';
            $this->validateCsrfToken($token);

            // Obtener tarea
            $task = $this->db->fetchOne(
                "SELECT t.*, pbi.project_id, pbi.title as item_title
                 FROM tasks t
                 JOIN product_backlog_items pbi ON t.backlog_item_id = pbi.id
                 WHERE t.id = ?",
                [$id]
            );

            if (!$task) {
                throw new \Exception('Tarea no encontrada');
            }

            // Eliminar tarea
            $this->db->query("DELETE FROM tasks WHERE id = ?", [$id]);

            // Actualizar horas del backlog item
            $this->updateBacklogItemHours($task['backlog_item_id']);

            // Registrar en historial (opcional, no crítico)
            if (!empty($task['project_id'])) {
                try {
                    $this->db->query(
                        "INSERT INTO project_history (project_id, user_id, action, field_name, old_value)
                         VALUES (?, ?, ?, ?, ?)",
                        [
                            $task['project_id'],
                            $_SESSION['user']['id'],
                            'eliminó la tarea',
                            'task',
                            $task['title']
                        ]
                    );
                } catch (\Exception $e) {
                    error_log("Warning: Could not insert into project_history: " . $e->getMessage());
                    // Continuar sin error
                }
            }

            echo json_encode(['success' => true, 'message' => 'Tarea eliminada']);
            exit;

        } catch (\Exception $e) {
            error_log("Error deleting task: " . $e->getMessage());
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
            exit;
        }
    }

    /**
     * Actualizar horas totales del backlog item sumando las horas de sus tareas
     */
    private function updateBacklogItemHours($backlogItemId)
    {
        // Sumar horas reales de todas las tareas
        $result = $this->db->fetchOne(
            "SELECT SUM(actual_hours) as total_hours FROM tasks WHERE backlog_item_id = ?",
            [$backlogItemId]
        );

        $totalHours = $result['total_hours'] ?? 0;

        // Actualizar en sprint_backlog si el item está en un sprint
        $this->db->query(
            "UPDATE sprint_backlog 
             SET actual_hours = ?
             WHERE backlog_item_id = ?",
            [$totalHours, $backlogItemId]
        );
    }

    /**
     * Actualizar progreso del proyecto
     */
    private function updateProjectProgress($projectId)
    {
        // Contar requerimientos completados
        $reqResult = $this->db->fetchOne(
            "SELECT COUNT(*) as completed
             FROM requirements 
             WHERE project_id = ? AND status = 'completed'",
            [$projectId]
        );

        $completedReqs = $reqResult['completed'] ?? 0;

        // Contar backlog items completados
        $itemResult = $this->db->fetchOne(
            "SELECT COUNT(*) as done
             FROM product_backlog_items 
             WHERE project_id = ? AND status = 'done'",
            [$projectId]
        );

        $doneItems = $itemResult['done'] ?? 0;

        // Contar total de items
        $totalResult = $this->db->fetchOne(
            "SELECT 
                (SELECT COUNT(*) FROM requirements WHERE project_id = ?) +
                (SELECT COUNT(*) FROM product_backlog_items WHERE project_id = ?) as total",
            [$projectId, $projectId]
        );

        $total = $totalResult['total'] ?? 0;

        $progress = 0;
        if ($total > 0) {
            $progress = round((($completedReqs + $doneItems) / $total) * 100, 2);
        }

        $this->db->query(
            "UPDATE projects SET progress_percentage = ? WHERE id = ?",
            [$progress, $projectId]
        );
    }

    /**
     * Obtener tareas de un backlog item (API)
     */
    public function getTasks($backlogItemId)
    {
        try {
            $tasks = $this->db->fetchAll(
                "SELECT t.*, 
                        u.first_name as assigned_first_name, 
                        u.last_name as assigned_last_name
                 FROM tasks t
                 LEFT JOIN users u ON t.assigned_to = u.id
                 WHERE t.backlog_item_id = ?
                 ORDER BY t.created_at ASC",
                [$backlogItemId]
            );

            echo json_encode(['success' => true, 'tasks' => $tasks]);
            exit;

        } catch (\Exception $e) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
            exit;
        }
    }
}
