<?php
require_once __DIR__ . "/../../bootstrap.php";
require_once __DIR__ . '/../../src/AdminAuth.php';
AdminAuth::requireLogin();

if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

$pageTitle = "Liste des TFE";
require_once __DIR__ . '/../../src/Database.php';

// ── CSV Import (inline, submitted to this same page) ─────────────────────────
$importMessage = '';
$importErrors  = [];
$importResults = [];
$importDone    = false;

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
    if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        $importErrors[] = "Erreur de sécurité : token invalide.";
    } else {
        $importedCount = 0;
        $skippedCount  = 0;
        try {
            $importDb  = new Database();
            $importPdo = $importDb->getPDO();

            if ($_FILES['csv_file']['error'] !== UPLOAD_ERR_OK) {
                throw new Exception("Erreur lors du téléversement du fichier.");
            }

            $handle = fopen($_FILES['csv_file']['tmp_name'], 'r');
            if (!$handle) throw new Exception("Impossible d'ouvrir le fichier CSV.");

            fgetcsv($handle, 0, ',', '"', '');
            fgetcsv($handle, 0, ',', '"', '');
            fgetcsv($handle, 0, ',', '"', '');
            fgetcsv($handle, 0, ',', '"', ''); // skip 4 header rows

            // Code → canonical name (legacy short-code CSV format)
            $orientationCodeMap = [
                'SC'=>'Sculpture','VI'=>'Vidéographie','CA'=>"Cinéma d'animation",
                'IP'=>'Installation-Performance','PE'=>'Peinture','PH'=>'Photographie',
                'DE'=>'Dessin','AN'=>'Arts Numériques','GR'=>'Graphisme',
                'TY'=>'Typographie','DN'=>'Design Numérique','IL'=>'Illustration',
                'BD'=>'Bande-Dessinée','SE'=>'Sérigraphie','GV'=>'Gravure',
            ];

            // Alias map: normalise known variant spellings → canonical DB name.
            // Keys are lowercased+stripped for comparison.
            $orientationAliases = [
                'arts numériques'         => 'Arts Numériques',
                'design numérique'        => 'Design Numérique',
                'installation/performance' => 'Installation-Performance',
                'installation performance' => 'Installation-Performance',
                'cinema d\'animation'     => "Cinéma d'animation",
                'cinéma d\'animation'     => "Cinéma d'animation",
                'bande dessinée'          => 'Bande-Dessinée',
            ];

            // Resolve an orientation string (code or full name) → canonical DB name.
            $resolveOrientation = function(string $raw) use ($orientationCodeMap, $orientationAliases, $importPdo): ?int {
                $raw = trim($raw);
                if ($raw === '') return null;

                // 1. Try legacy short code
                if (isset($orientationCodeMap[$raw])) {
                    $raw = $orientationCodeMap[$raw];
                }

                // 2. Try alias map (lowercase key)
                $key = mb_strtolower($raw, 'UTF-8');
                if (isset($orientationAliases[$key])) {
                    $raw = $orientationAliases[$key];
                }

                // 3. Exact DB match
                $s = $importPdo->prepare("SELECT id FROM orientations WHERE name = ?");
                $s->execute([$raw]);
                $r = $s->fetch();
                if ($r) return (int)$r['id'];

                // 4. Case-insensitive DB match
                $s = $importPdo->prepare("SELECT id FROM orientations WHERE LOWER(name) = LOWER(?)");
                $s->execute([$raw]);
                $r = $s->fetch();
                return $r ? (int)$r['id'] : null;
            };

            // AP alias map: variant spellings → canonical DB name.
            $apAliases = [
                'l.i.e.n.s.'                => 'Lieux, Interdisciplinarités, Écologie, Nécessité, Systèmes',
                'liens'                     => 'Lieux, Interdisciplinarités, Écologie, Nécessité, Systèmes',
                'lieux, interdisciplinarités, écologie, nécessité, systèmes'
                                            => 'Lieux, Interdisciplinarités, Écologie, Nécessité, Systèmes',
                'récits et expérimentation' => 'Récits et expérimentation',
                'recits et experimentation' => 'Récits et expérimentation',
                'atelier pratiques situées' => 'Atelier Pratiques Situées',
                'design et politique du multiple' => 'Design et Politique du Multiple',
                'narration spéculative'     => 'Narration Spéculative',
                'pacs'                      => 'PACS',
            ];

            // Resolve an AP string (code or full name) → ap_program id.
            $resolveAP = function(string $raw) use ($apAliases, $importPdo): ?int {
                $raw = trim($raw);
                if ($raw === '') return null;

                // 1. Try alias map (lowercase key)
                $key = mb_strtolower($raw, 'UTF-8');
                if (isset($apAliases[$key])) {
                    $raw = $apAliases[$key];
                }

                // 2. Exact name match
                $s = $importPdo->prepare("SELECT id FROM ap_programs WHERE name = ?");
                $s->execute([$raw]);
                $r = $s->fetch();
                if ($r) return (int)$r['id'];

                // 3. Code match (legacy)
                $s = $importPdo->prepare("SELECT id FROM ap_programs WHERE code = ?");
                $s->execute([$raw]);
                $r = $s->fetch();
                if ($r) return (int)$r['id'];

                // 4. Case-insensitive name match
                $s = $importPdo->prepare("SELECT id FROM ap_programs WHERE LOWER(name) = LOWER(?)");
                $s->execute([$raw]);
                $r = $s->fetch();
                return $r ? (int)$r['id'] : null;
            };

            $lineNumber = 5;
            while (($row = fgetcsv($handle, 0, ',', '"', '')) !== false) {
                $lineNumber++;
                if (empty($row[0]) && empty($row[1])) continue;
                try {
                    $importDb->beginTransaction();

                    $identifier      = trim($row[0]  ?? '');
                    $title           = trim($row[1]  ?? '');
                    $subtitle        = trim($row[2]  ?? '');
                    $authorsRaw      = trim($row[3]  ?? '');
                    $contact         = trim($row[4]  ?? '');
                    $supervisorsRaw  = trim($row[5]  ?? '');
                    $formatsRaw      = trim($row[6]  ?? '');
                    $year            = intval($row[7] ?? 0);
                    $apCode          = trim($row[8]  ?? '');
                    $orientationCode = trim($row[9]  ?? '');
                    $finalityName    = trim($row[10] ?? '');
                    $keywordsRaw     = trim($row[11] ?? '');
                    $synopsis        = trim($row[12] ?? '');
                    $context         = trim($row[13] ?? '');
                    $remarks         = trim($row[14] ?? '');
                    $languageRaw     = trim($row[15] ?? '');
                    $access          = trim($row[16] ?? '');
                    $license         = trim($row[17] ?? '');
                    $sizeInfo        = trim($row[18] ?? '');
                    $juryPoints      = !empty($row[19]) ? floatval($row[19]) : null;
                    $baiuLink        = trim($row[20] ?? '');

                    if (empty($title) || empty($year)) throw new Exception("Titre et année requis.");

                    $orientationId = $resolveOrientation($orientationCode);
                    $apProgramId   = $resolveAP($apCode);

                    $finalityId = null;
                    if (!empty($finalityName)) {
                        $s = $importPdo->prepare("SELECT id FROM finality_types WHERE name = ?");
                        $s->execute([$finalityName]);
                        $r = $s->fetch(); $finalityId = $r ? $r['id'] : null;
                    }

                    $accessTypeId = null;
                    if (!empty($access)) {
                        $s = $importPdo->prepare("SELECT id FROM access_types WHERE name = ?");
                        $s->execute([ucfirst(strtolower($access))]);
                        $r = $s->fetch(); $accessTypeId = $r ? $r['id'] : null;
                    }
                    if ($accessTypeId === null) $accessTypeId = 1;

                    if (!empty($identifier)) {
                        $s = $importPdo->prepare("SELECT id FROM theses WHERE identifier = ?");
                        $s->execute([$identifier]);
                        if ($s->fetch()) {
                            $importDb->rollback();
                            $skippedCount++;
                            $importResults[] = ['type'=>'skip', 'msg'=>"Ligne $lineNumber: identifiant \"$identifier\" déjà présent, ignoré."];
                            continue;
                        }
                    }

                    $s = $importPdo->prepare("
                        INSERT INTO theses (
                            identifier, title, subtitle, year,
                            orientation_id, ap_program_id, finality_id,
                            synopsis, context_note, remarks,
                            file_size_info, jury_points, baiu_link,
                            access_type_id, is_published, submitted_at
                        ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,1,CURRENT_TIMESTAMP)
                    ");
                    $s->execute([
                        !empty($identifier) ? $identifier : null, $title,
                        !empty($subtitle)   ? $subtitle   : null, $year,
                        $orientationId, $apProgramId, $finalityId,
                        !empty($synopsis)  ? $synopsis  : null,
                        !empty($context)   ? $context   : null,
                        !empty($remarks)   ? $remarks   : null,
                        !empty($sizeInfo)  ? $sizeInfo  : null,
                        $juryPoints,
                        !empty($baiuLink)  ? $baiuLink  : null,
                        $accessTypeId,
                    ]);
                    $thesisId = $importPdo->lastInsertId();

                    if (!empty($authorsRaw)) {
                        foreach (array_map('trim', explode(',', $authorsRaw)) as $idx => $name) {
                            if ($name) {
                                $aId = $importDb->findOrCreateAuthor($name, $idx === 0 ? $contact : null);
                                $s = $importPdo->prepare("INSERT INTO thesis_authors (thesis_id, author_id, author_order) VALUES (?,?,?)");
                                $s->execute([$thesisId, $aId, $idx + 1]);
                            }
                        }
                    }
                    if (!empty($supervisorsRaw)) {
                        foreach (array_map('trim', explode(',', $supervisorsRaw)) as $idx => $name) {
                            if ($name) {
                                $sId = $importDb->findOrCreateSupervisor($name);
                                $s = $importPdo->prepare("INSERT INTO thesis_supervisors (thesis_id, supervisor_id, supervisor_order) VALUES (?,?,?)");
                                $s->execute([$thesisId, $sId, $idx + 1]);
                            }
                        }
                    }
                    if (!empty($keywordsRaw)) {
                        foreach (array_slice(array_map('trim', explode(',', $keywordsRaw)), 0, 10) as $kw) {
                            if ($kw) {
                                $tId = $importDb->findOrCreateTag($kw);
                                if ($tId) {
                                    $s = $importPdo->prepare("INSERT INTO thesis_tags (thesis_id, tag_id) VALUES (?,?)");
                                    $s->execute([$thesisId, $tId]);
                                }
                            }
                        }
                    }
                    if (!empty($languageRaw)) {
                        $s = $importPdo->prepare("SELECT id FROM languages WHERE name = ?");
                        $s->execute([ucfirst(strtolower($languageRaw))]);
                        $r = $s->fetch();
                        if ($r) {
                            $s2 = $importPdo->prepare("INSERT INTO thesis_languages (thesis_id, language_id) VALUES (?,?)");
                            $s2->execute([$thesisId, $r['id']]);
                        }
                    }
                    if (!empty($formatsRaw)) {
                        foreach (array_map('trim', explode(',', $formatsRaw)) as $fmt) {
                            if ($fmt) {
                                $s = $importPdo->prepare("SELECT id FROM format_types WHERE name = ?");
                                $s->execute([ucfirst(strtolower($fmt))]);
                                $r = $s->fetch();
                                if ($r) {
                                    $s2 = $importPdo->prepare("INSERT INTO thesis_formats (thesis_id, format_id) VALUES (?,?)");
                                    $s2->execute([$thesisId, $r['id']]);
                                }
                            }
                        }
                    }

                    $importDb->commit();
                    $importedCount++;
                    $importResults[] = ['type'=>'ok', 'msg'=>"\"$title\" (ID: $thesisId)"];

                } catch (Exception $e) {
                    $importDb->rollback();
                    $skippedCount++;
                    $importResults[] = ['type'=>'error', 'msg'=>"Ligne $lineNumber: " . $e->getMessage()];
                    error_log("Import error on line $lineNumber: " . $e->getMessage());
                }
            }
            fclose($handle);
            $importMessage = "Import terminé : $importedCount TFE importés, $skippedCount ignorés.";
            $importDone = true;
        } catch (Exception $e) {
            $importErrors[] = $e->getMessage();
            error_log("CSV import error: " . $e->getMessage());
        }
    }
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

try {
    $db = new Database();
    $searchQuery       = isset($_GET['search'])      ? trim($_GET['search'])       : '';
    $yearFilter        = isset($_GET['year'])         ? intval($_GET['year'])        : null;
    $orientationFilter = isset($_GET['orientation']) ? intval($_GET['orientation']) : null;
    $apFilter          = isset($_GET['ap'])           ? intval($_GET['ap'])          : null;

    $sortCol  = isset($_GET['sort'])  ? trim($_GET['sort'])  : 'submitted_at';
    $sortDir  = isset($_GET['dir'])   ? trim($_GET['dir'])   : 'desc';

    $filters = [];
    if ($searchQuery)       $filters['search']      = $searchQuery;
    if ($yearFilter)        $filters['year']        = $yearFilter;
    if ($orientationFilter) $filters['orientation'] = $orientationFilter;
    if ($apFilter)          $filters['ap']          = $apFilter;
    $filters['sort'] = $sortCol;
    $filters['dir']  = $sortDir;

    $perPage    = 25;
    $page       = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
    $totalCount = $db->getThesesListCount($filters);
    $totalPages = $totalCount > 0 ? (int) ceil($totalCount / $perPage) : 1;
    $page       = min($page, $totalPages);
    $offset     = ($page - 1) * $perPage;

    $theses       = $db->getThesesList($filters, $perPage, $offset);
    $stats        = $db->getThesesStats();
    $years        = $db->getAllYears();
    $orientations = $db->getAllOrientations();
    $apPrograms   = $db->getAllAPPrograms();
} catch (Exception $e) {
    error_log("Error loading theses list: " . $e->getMessage());
    die("Erreur lors du chargement de la liste.");
}

$isAdmin = true; $bodyClass = 'admin-body';
require_once APP_ROOT . '/templates/head.php';
include APP_ROOT . '/templates/header.php';
include APP_ROOT . '/templates/admin/index.php';
require_once APP_ROOT . '/templates/admin/footer.php';

