<?php

class TaskManager {
    private $pdo;
    
    public function __construct($pdo) {
        $this->pdo = $pdo;
    }
    
    public function getDailyTasks($userId) {
        // 1. Check for incomplete tasks from previous days
        $incompleteTasks = $this->getIncompleteTasks($userId);
        if (!empty($incompleteTasks)) {
            return $incompleteTasks;
        }
        
        // 2. Check for today's tasks
        $todaysTasks = $this->getTodaysTasks($userId);
        if (!empty($todaysTasks)) {
            return $todaysTasks;
        }
        
        // 3. If no tasks for today, assign new ones
        return $this->assignDailyTasks($userId);
    }
    
    private function getIncompleteTasks($userId) {
        $stmt = $this->pdo->prepare("
            SELECT ut.*, t.instruction_text, t.tips_text, t.sample_audio_url, c.name as category_name
            FROM user_tasks ut
            JOIN tasks t ON ut.task_id = t.id
            JOIN task_categories c ON t.category_id = c.id
            WHERE ut.user_id = ? 
            AND ut.status = 'assigned'
            AND ut.assigned_date < CURDATE()
            ORDER BY ut.assigned_date, c.id
        ");
        $stmt->execute([$userId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    private function getTodaysTasks($userId) {
        $stmt = $this->pdo->prepare("
            SELECT ut.*, t.instruction_text, t.tips_text, t.sample_audio_url, c.name as category_name
            FROM user_tasks ut
            JOIN tasks t ON ut.task_id = t.id
            JOIN task_categories c ON t.category_id = c.id
            WHERE ut.user_id = ? 
            AND ut.assigned_date = CURDATE()
            ORDER BY c.id
        ");
        $stmt->execute([$userId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    private function assignDailyTasks($userId) {
        // Get user's join date
        $stmt = $this->pdo->prepare("SELECT created_at FROM users WHERE id = ?");
        $stmt->execute([$userId]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$user) {
            throw new Exception("User not found");
        }
        
        // Get all categories
        $categories = $this->pdo->query("
            SELECT id FROM task_categories ORDER BY id
        ")->fetchAll(PDO::FETCH_COLUMN);
        
        $assignedTasks = [];
        
        // Start transaction
        $this->pdo->beginTransaction();
        
        try {
            foreach ($categories as $categoryId) {
                // Get the next uncompleted task for this category
                // This ensures we go through all tasks sequentially without cycling
                $stmt = $this->pdo->prepare("
                    SELECT t.id 
                    FROM tasks t
                    WHERE t.category_id = ?
                    AND t.id NOT IN (
                        SELECT task_id 
                        FROM user_tasks 
                        WHERE user_id = ? 
                        AND category_id = ?
                        AND status = 'completed'
                    )
                    ORDER BY t.id
                    LIMIT 1
                ");
                $stmt->execute([$categoryId, $userId, $categoryId]);
                $task = $stmt->fetch(PDO::FETCH_ASSOC);
                
                if ($task) {
                    // Insert into user_tasks
                    $stmt = $this->pdo->prepare("
                        INSERT INTO user_tasks 
                        (user_id, task_id, category_id, assigned_date, status)
                        VALUES (?, ?, ?, CURDATE(), 'assigned')
                        ON DUPLICATE KEY UPDATE status = 'assigned'
                    ");
                    $stmt->execute([$userId, $task['id'], $categoryId]);
                    
                    // Get full task details
                    $taskDetails = $this->pdo->prepare("
                        SELECT ut.*, t.instruction_text, t.tips_text, t.sample_audio_url, c.name as category_name
                        FROM tasks t
                        JOIN task_categories c ON t.category_id = c.id
                        LEFT JOIN user_tasks ut ON ut.task_id = t.id 
                            AND ut.user_id = ?
                            AND ut.assigned_date = CURDATE()
                        WHERE t.id = ?
                    ");
                    $taskDetails->execute([$userId, $task['id']]);
                    $assignedTasks[] = $taskDetails->fetch(PDO::FETCH_ASSOC);
                }
            }
            
            $this->pdo->commit();
            return $assignedTasks;
            
        } catch (Exception $e) {
            $this->pdo->rollBack();
            throw $e;
        }
    }
    
    public function completeTask($userId, $taskId) {
        try {
            // Start transaction
            $this->pdo->beginTransaction();
            
            // First, verify the task exists and is assigned to the user
            $checkStmt = $this->pdo->prepare("
                SELECT id, task_id FROM user_tasks 
                WHERE user_id = ? AND task_id = ? AND status = 'assigned' AND DATE(assigned_date) = CURDATE()
                LIMIT 1
            ");
            $checkStmt->execute([$userId, $taskId]);
            $task = $checkStmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$task) {
                throw new Exception("Task not found or already completed");
            }
            
            // Update the task status
            $updateStmt = $this->pdo->prepare("
                UPDATE user_tasks 
                SET status = 'completed', 
                    completed_at = NOW(),
                    updated_at = NOW()
                WHERE id = ?
                AND status = 'assigned'
            ");
            
            $result = $updateStmt->execute([$task['id']]);
            
            if ($result && $updateStmt->rowCount() > 0) {
                // Update user stats - check if last_updated column exists
                $columnCheck = $this->pdo->query("
                    SELECT COUNT(*) as has_column
                    FROM information_schema.COLUMNS 
                    WHERE TABLE_SCHEMA = DATABASE() 
                    AND TABLE_NAME = 'user_stats' 
                    AND COLUMN_NAME = 'last_updated'
                ")->fetch(PDO::FETCH_ASSOC);
                
                if ($columnCheck['has_column'] > 0) {
                    // Use last_updated column
                    $updateStats = $this->pdo->prepare("
                        INSERT INTO user_stats (user_id, points, today_completed, last_updated)
                        VALUES (?, 10, 1, NOW())
                        ON DUPLICATE KEY UPDATE 
                            points = points + 10,
                            today_completed = IF(DATE(last_updated) = CURDATE(), today_completed + 1, 1),
                            last_updated = NOW()
                    ");
                } else {
                    // Fall back to last_participation
                    $updateStats = $this->pdo->prepare("
                        INSERT INTO user_stats (user_id, points, today_completed, last_participation)
                        VALUES (?, 10, 1, CURDATE())
                        ON DUPLICATE KEY UPDATE 
                            points = points + 10,
                            today_completed = IF(DATE(last_participation) = CURDATE(), today_completed + 1, 1),
                            last_participation = CURDATE()
                    ");
                }
                $updateStats->execute([$userId]);
                
                $this->pdo->commit();
                return true;
            }
            
            $this->pdo->rollBack();
            return false;
            
        } catch (Exception $e) {
            $this->pdo->rollBack();
            error_log("Error completing task: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Get user's task progress for today
     * @param int $userId
     * @return array [completed, total, next_task_index]
     */
    public function getUserTaskProgress($userId) {
        // First, ensure user has tasks for today
        $hasTasks = $this->getTodaysTasks($userId);
        if (empty($hasTasks)) {
            // If no tasks, assign them
            $this->assignDailyTasks($userId);
        }
        
        // Get total tasks for today
        $stmt = $this->pdo->prepare("
            SELECT 
                COUNT(*) as total,
                SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed
            FROM user_tasks 
            WHERE user_id = ? 
            AND DATE(assigned_date) = CURDATE()
        ");
        $stmt->execute([$userId]);
        $progress = $stmt->fetch(PDO::FETCH_ASSOC);
        
        // Get the next task index (1-based)
        $stmt = $this->pdo->prepare("
            SELECT COUNT(*) + 1 as next_index
            FROM user_tasks
            WHERE user_id = ? 
            AND DATE(assigned_date) = CURDATE()
            AND status = 'completed'
        ");
        $stmt->execute([$userId]);
        $nextIndex = $stmt->fetchColumn();
        
        // Ensure we have at least 1 task
        $totalTasks = max((int)($progress['total'] ?? 8), 1);
        $completed = (int)($progress['completed'] ?? 0);
        $nextIndex = max(1, min((int)$nextIndex, $totalTasks));
        
        return [
            'completed' => $completed,
            'total' => $totalTasks,
            'next_index' => $nextIndex
        ];
    }
    
    public function getCompletedTasksToday($userId) {
        $stmt = $this->pdo->prepare("
            SELECT COUNT(*) as count 
            FROM user_tasks 
            WHERE user_id = ? 
            AND DATE(completed_at) = CURDATE()
            AND status = 'completed'
        ");
        $stmt->execute([$userId]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        return $result ? $result['count'] : 0;
    }
    
    public function getTotalTasksToday($userId) {
        $stmt = $this->pdo->prepare("
            SELECT COUNT(*) as count 
            FROM user_tasks 
            WHERE user_id = ? 
            AND assigned_date = CURDATE()
        ");
        $stmt->execute([$userId]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        return $result ? $result['count'] : 0;
    }
}
