<?php
/**
 * Rubric Tree Functions
 * Recursive functions for Kent's Repertory hierarchy
 */

require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/functions.php';

// ============================================
// TREE BUILDING FUNCTIONS
// ============================================

/**
 * Get complete rubric tree as nested array
 * @param int|null $parentId
 * @return array
 */
function getRubricTreeArray($parentId = null) {
    $pdo = getDB();
    
    $sql = "SELECT * FROM rubrics WHERE parent_id " . 
           ($parentId === null ? "IS NULL" : "= ?") . 
           " ORDER BY sort_order, rubric_name";
    
    $stmt = $pdo->prepare($sql);
    if ($parentId !== null) {
        $stmt->execute([$parentId]);
    } else {
        $stmt->execute();
    }
    
    $rubrics = $stmt->fetchAll();
    
    foreach ($rubrics as &$rubric) {
        $rubric['children'] = getRubricTreeArray($rubric['id']);
        $rubric['remedies'] = getRubricRemedies($rubric['id']);
    }
    
    return $rubrics;
}

/**
 * Get rubric tree as HTML (recursive)
 * @param int|null $parentId
 * @param int $level
 * @return string
 */
function getRubricTreeHTML($parentId = null, $level = 0) {
    $pdo = getDB();
    
    $sql = "SELECT * FROM rubrics WHERE parent_id " . 
           ($parentId === null ? "IS NULL" : "= ?") . 
           " ORDER BY sort_order, rubric_name";
    
    $stmt = $pdo->prepare($sql);
    if ($parentId !== null) {
        $stmt->execute([$parentId]);
    } else {
        $stmt->execute();
    }
    
    $rubrics = $stmt->fetchAll();
    $html = '';
    
    foreach ($rubrics as $rubric) {
        $hasChildren = hasRubricChildren($rubric['id']);
        $remedies = getRubricRemedies($rubric['id']);
        $indent = $level * 20;
        
        $html .= '<div class="rubric-node" data-id="' . $rubric['id'] . '" data-level="' . $rubric['level'] . '">';
        $html .= '<div class="rubric-item" style="margin-left: ' . $indent . 'px;">';
        
        // Toggle icon for children
        if ($hasChildren) {
            $html .= '<span class="toggle-icon">▼</span>';
        } else {
            $html .= '<span class="toggle-icon-placeholder"></span>';
        }
        
        // Rubric name with appropriate styling
        if ($rubric['level'] == 1) {
            $html .= '<strong class="chapter-name">' . escape($rubric['rubric_name']) . '</strong>';
        } else {
            $html .= '<span class="rubric-name" onclick="selectRubric(' . $rubric['id'] . ', \'' . escape($rubric['full_path']) . '\')">' 
                   . escape($rubric['rubric_name']) . '</span>';
        }
        
        // Display remedies if any
        if (!empty($remedies)) {
            $html .= '<div class="remedy-list">';
            foreach ($remedies as $remedy) {
                $html .= '<span class="' . $remedy['css_class'] . '" title="Grade ' . $remedy['grade'] . '">'
                       . escape($remedy['name']) . '</span>';
            }
            $html .= '</div>';
        }
        
        // Admin actions
        if (isAdmin()) {
            $html .= '<div class="rubric-actions">';
            $html .= '<button class="btn-edit" onclick="editRubric(' . $rubric['id'] . ')">✏️</button>';
            $html .= '<button class="btn-add" onclick="addChildRubric(' . $rubric['id'] . ')">➕</button>';
            $html .= '<button class="btn-delete" onclick="deleteRubric(' . $rubric['id'] . ')">🗑️</button>';
            $html .= '</div>';
        }
        
        $html .= '</div>';
        
        // Render children recursively
        if ($hasChildren) {
            $html .= '<div class="rubric-children">';
            $html .= getRubricTreeHTML($rubric['id'], $level + 1);
            $html .= '</div>';
        }
        
        $html .= '</div>';
    }
    
    return $html;
}

/**
 * Get rubric select options (for dropdowns)
 * @param int|null $selectedId
 * @param int|null $parentId
 * @param string $prefix
 * @return string
 */
function getRubricSelectOptions($selectedId = null, $parentId = null, $prefix = '') {
    $pdo = getDB();
    
    $sql = "SELECT * FROM rubrics WHERE parent_id " . 
           ($parentId === null ? "IS NULL" : "= ?") . 
           " ORDER BY rubric_name";
    
    $stmt = $pdo->prepare($sql);
    if ($parentId !== null) {
        $stmt->execute([$parentId]);
    } else {
        $stmt->execute();
    }
    
    $rubrics = $stmt->fetchAll();
    $html = '';
    
    foreach ($rubrics as $rubric) {
        $selected = ($selectedId == $rubric['id']) ? 'selected' : '';
        $html .= '<option value="' . $rubric['id'] . '" ' . $selected . '>';
        $html .= $prefix . escape($rubric['rubric_name']);
        $html .= '</option>';
        
        // Add children with increased prefix
        $html .= getRubricSelectOptions($selectedId, $rubric['id'], $prefix . '-- ');
    }
    
    return $html;
}

// ============================================
// RUBRIC QUERY FUNCTIONS
// ============================================

/**
 * Get rubric by ID
 * @param int $rubricId
 * @return array|null
 */
function getRubric($rubricId) {
    $pdo = getDB();
    $stmt = $pdo->prepare("SELECT * FROM rubrics WHERE id = ?");
    $stmt->execute([$rubricId]);
    return $stmt->fetch();
}

/**
 * Get rubric by full path
 * @param string $fullPath
 * @return array|null
 */
function getRubricByPath($fullPath) {
    $pdo = getDB();
    $stmt = $pdo->prepare("SELECT * FROM rubrics WHERE full_path = ?");
    $stmt->execute([$fullPath]);
    return $stmt->fetch();
}

/**
 * Check if rubric has children
 * @param int $rubricId
 * @return bool
 */
function hasRubricChildren($rubricId) {
    $pdo = getDB();
    $stmt = $pdo->prepare("SELECT COUNT(*) as count FROM rubrics WHERE parent_id = ?");
    $stmt->execute([$rubricId]);
    $result = $stmt->fetch();
    return $result['count'] > 0;
}

/**
 * Get child rubrics
 * @param int $rubricId
 * @return array
 */
function getChildRubrics($rubricId) {
    $pdo = getDB();
    $stmt = $pdo->prepare("SELECT * FROM rubrics WHERE parent_id = ? ORDER BY sort_order, rubric_name");
    $stmt->execute([$rubricId]);
    return $stmt->fetchAll();
}

/**
 * Get parent rubric
 * @param int $rubricId
 * @return array|null
 */
function getParentRubric($rubricId) {
    $rubric = getRubric($rubricId);
    if (!$rubric || !$rubric['parent_id']) {
        return null;
    }
    return getRubric($rubric['parent_id']);
}

/**
 * Get rubric path as array (breadcrumbs)
 * @param int $rubricId
 * @return array
 */
function getRubricPath($rubricId) {
    $path = [];
    $currentId = $rubricId;
    
    while ($currentId) {
        $rubric = getRubric($currentId);
        if (!$rubric) break;
        array_unshift($path, $rubric);
        $currentId = $rubric['parent_id'];
    }
    
    return $path;
}

/**
 * Get full path string for breadcrumbs
 * @param int $rubricId
 * @param string $separator
 * @return string
 */
function getRubricBreadcrumbs($rubricId, $separator = ' > ') {
    $path = getRubricPath($rubricId);
    $breadcrumbs = array_column($path, 'rubric_name');
    return implode($separator, $breadcrumbs);
}

// ============================================
// RUBRIC REMEDY FUNCTIONS
// ============================================

/**
 * Get remedies for a rubric with grade styling
 * @param int $rubricId
 * @return array
 */
function getRubricRemedies($rubricId) {
    $pdo = getDB();
    
    $sql = "SELECT r.id, r.name, rr.grade
            FROM rubric_remedy rr
            JOIN remedies r ON rr.remedy_id = r.id
            WHERE rr.rubric_id = ?
            ORDER BY rr.grade DESC, r.name";
    
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$rubricId]);
    $remedies = $stmt->fetchAll();
    
    foreach ($remedies as &$remedy) {
        $remedy['css_class'] = getGradeClass($remedy['grade']);
        $remedy['weight'] = getGradeWeight($remedy['grade']);
    }
    
    return $remedies;
}

/**
 * Get all rubrics containing a specific remedy
 * @param int $remedyId
 * @return array
 */
function getRubricsByRemedy($remedyId) {
    $pdo = getDB();
    
    $sql = "SELECT r.*, rr.grade
            FROM rubric_remedy rr
            JOIN rubrics r ON rr.rubric_id = r.id
            WHERE rr.remedy_id = ?
            ORDER BY r.full_path";
    
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$remedyId]);
    return $stmt->fetchAll();
}

/**
 * Add remedy to rubric with grade
 * @param int $rubricId
 * @param int $remedyId
 * @param int $grade
 * @return bool
 */
function addRemedyToRubric($rubricId, $remedyId, $grade) {
    $pdo = getDB();
    
    // Check if exists
    $stmt = $pdo->prepare("SELECT id FROM rubric_remedy WHERE rubric_id = ? AND remedy_id = ?");
    $stmt->execute([$rubricId, $remedyId]);
    
    if ($stmt->fetch()) {
        // Update grade
        $stmt = $pdo->prepare("UPDATE rubric_remedy SET grade = ? WHERE rubric_id = ? AND remedy_id = ?");
        return $stmt->execute([$grade, $rubricId, $remedyId]);
    } else {
        // Insert new
        $stmt = $pdo->prepare("INSERT INTO rubric_remedy (rubric_id, remedy_id, grade) VALUES (?, ?, ?)");
        return $stmt->execute([$rubricId, $remedyId, $grade]);
    }
}

/**
 * Remove remedy from rubric
 * @param int $rubricId
 * @param int $remedyId
 * @return bool
 */
function removeRemedyFromRubric($rubricId, $remedyId) {
    $pdo = getDB();
    $stmt = $pdo->prepare("DELETE FROM rubric_remedy WHERE rubric_id = ? AND remedy_id = ?");
    return $stmt->execute([$rubricId, $remedyId]);
}

// ============================================
// RUBRIC CRUD OPERATIONS
// ============================================

/**
 * Create new rubric
 * @param array $data
 * @return int|false (rubric ID or false)
 */
function createRubric($data) {
    $pdo = getDB();
    
    // Calculate full path and level
    if ($data['parent_id']) {
        $parent = getRubric($data['parent_id']);
        if (!$parent) return false;
        
        $fullPath = $parent['full_path'] . ' - ' . $data['rubric_name'];
        $level = $parent['level'] + 1;
        $chapterName = $parent['chapter_name'];
    } else {
        $fullPath = $data['rubric_name'];
        $level = 1;
        $chapterName = $data['rubric_name'];
    }
    
    $sql = "INSERT INTO rubrics (parent_id, chapter_name, rubric_name, full_path, level, sort_order) 
            VALUES (?, ?, ?, ?, ?, ?)";
    
    $stmt = $pdo->prepare($sql);
    $result = $stmt->execute([
        $data['parent_id'] ?: null,
        $chapterName,
        $data['rubric_name'],
        $fullPath,
        $level,
        $data['sort_order'] ?? 0
    ]);
    
    if ($result) {
        return $pdo->lastInsertId();
    }
    
    return false;
}

/**
 * Update rubric
 * @param int $rubricId
 * @param array $data
 * @return bool
 */
function updateRubric($rubricId, $data) {
    $pdo = getDB();
    
    $oldRubric = getRubric($rubricId);
    if (!$oldRubric) return false;
    
    $updates = [];
    $params = [];
    
    if (isset($data['rubric_name']) && $data['rubric_name'] != $oldRubric['rubric_name']) {
        $updates[] = "rubric_name = ?";
        $params[] = $data['rubric_name'];
        
        // Update full path
        $newFullPath = preg_replace('/[^-]+$/', $data['rubric_name'], $oldRubric['full_path']);
        $updates[] = "full_path = ?";
        $params[] = $newFullPath;
    }
    
    if (isset($data['sort_order'])) {
        $updates[] = "sort_order = ?";
        $params[] = $data['sort_order'];
    }
    
    if (empty($updates)) return true;
    
    $params[] = $rubricId;
    $sql = "UPDATE rubrics SET " . implode(', ', $updates) . " WHERE id = ?";
    $stmt = $pdo->prepare($sql);
    
    return $stmt->execute($params);
}

/**
 * Delete rubric and all children
 * @param int $rubricId
 * @return bool
 */
function deleteRubric($rubricId) {
    $pdo = getDB();
    
    // Delete will cascade to children due to foreign key
    $stmt = $pdo->prepare("DELETE FROM rubrics WHERE id = ?");
    return $stmt->execute([$rubricId]);
}

// ============================================
// SEARCH FUNCTIONS
// ============================================

/**
 * Search rubrics by name or path
 * @param string $query
 * @param int $limit
 * @return array
 */
function searchRubrics($query, $limit = 50) {
    $pdo = getDB();
    
    $searchTerm = '%' . $query . '%';
    $sql = "SELECT r.*, 
            (SELECT COUNT(*) FROM rubric_remedy WHERE rubric_id = r.id) as remedy_count
            FROM rubrics r
            WHERE r.rubric_name LIKE ? OR r.full_path LIKE ?
            ORDER BY r.level, r.rubric_name
            LIMIT ?";
    
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$searchTerm, $searchTerm, $limit]);
    return $stmt->fetchAll();
}

/**
 * Advanced rubric search with filters
 * @param array $filters
 * @return array
 */
function advancedRubricSearch($filters) {
    $pdo = getDB();
    $conditions = [];
    $params = [];
    
    if (!empty($filters['chapter'])) {
        $conditions[] = "chapter_name = ?";
        $params[] = $filters['chapter'];
    }
    
    if (!empty($filters['level'])) {
        $conditions[] = "level = ?";
        $params[] = $filters['level'];
    }
    
    if (!empty($filters['has_remedies'])) {
        $conditions[] = "EXISTS (SELECT 1 FROM rubric_remedy WHERE rubric_id = rubrics.id)";
    }
    
    if (!empty($filters['keyword'])) {
        $conditions[] = "(rubric_name LIKE ? OR full_path LIKE ?)";
        $params[] = '%' . $filters['keyword'] . '%';
        $params[] = '%' . $filters['keyword'] . '%';
    }
    
    $sql = "SELECT * FROM rubrics";
    if (!empty($conditions)) {
        $sql .= " WHERE " . implode(' AND ', $conditions);
    }
    $sql .= " ORDER BY full_path LIMIT 100";
    
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    return $stmt->fetchAll();
}

/**
 * Get rubric statistics
 * @return array
 */
function getRubricStatistics() {
    $pdo = getDB();
    $stats = [];
    
    // Total rubrics
    $stmt = $pdo->query("SELECT COUNT(*) as total FROM rubrics");
    $stats['total'] = $stmt->fetch()['total'];
    
    // By level
    $stmt = $pdo->query("SELECT level, COUNT(*) as count FROM rubrics GROUP BY level ORDER BY level");
    $stats['by_level'] = $stmt->fetchAll();
    
    // Chapters count
    $stmt = $pdo->query("SELECT COUNT(DISTINCT chapter_name) as chapters FROM rubrics WHERE level = 1");
    $stats['chapters'] = $stmt->fetch()['chapters'];
    
    // Rubrics with remedies
    $stmt = $pdo->query("SELECT COUNT(DISTINCT rubric_id) as count FROM rubric_remedy");
    $stats['with_remedies'] = $stmt->fetch()['count'];
    
    return $stats;
}