<?php

ini_set("display_errors",1);

if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];

require_once $baseDir . '/../scripts/session_functions.php';

ini_wkvs_session();

check_user_permission('wk_leitung');

verify_csrf();

if (!isset($_FILES['configFile']) || $_FILES['configFile']['error'] !== UPLOAD_ERR_OK) {
    echo json_encode([
        'success' => false,
        'message' => 'Keine Config-Datei ausgewählt'
    ]);
    exit;
}

$wkvsJSONVersion = '1.0.0';

$type = 'wkl';

$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';

if ($data['success'] === false){
	echo json_encode(['success' => false, 'message' => $data['message']]);
    exit; 
}

require $baseDir . '/../scripts/db/db-tables.php';
require $baseDir . '/../scripts/db/db-functions.php';
require $baseDir . '/../scripts/string-calculator/string-calculator-functions.php';



$saveDir = '/../private-files/config-uploads/';

$uploadDir = $baseDir . $saveDir;


if (!is_dir($uploadDir)) {
    mkdir($uploadDir, 0755, true);
}


$tmpPath = $_FILES['configFile']['tmp_name'];
$originalName = $_FILES['configFile']['name'];
$extension = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));

$allowedExt = ['json'];
if (!in_array($extension, $allowedExt, true)) {
    echo json_encode(['success' => false, 'message' => 'Falsches Format (Endung)']);
    http_response_code(422);
    exit;
}

$finfo = new finfo(FILEINFO_MIME_TYPE);
$mimeType = $finfo->file($tmpPath);
$allowedMime = ['application/json'];

if (!in_array($mimeType, $allowedMime, true)) {
    echo json_encode(['success' => false, 'message' => 'Dateiinhalt ist kein gültiges JSON']);
    http_response_code(422);
    exit;
}


$filename = date("Y_m_d_H_i_s") . '-wkvs-config.json';
$destination = $uploadDir . $filename;


if (!move_uploaded_file($tmpPath, $destination)) {
    http_response_code(500);
    exit;
}

$JSONcontent = file_get_contents($destination);

$content = json_decode($JSONcontent, true);
if (json_last_error() !== JSON_ERROR_NONE) {
    die("Invalid JSON layout.");
}

if (!isset($content['metadata']['wkvs_json_version']) || $content['metadata']['wkvs_json_version'] !== $wkvsJSONVersion) {
    echo json_encode(['success' => false, 'message' => 'Inkompatible Datei-Version. (V ' . $wkvsJSONVersion . ' benötigt'. (isset($content['metadata']['wkvs_json_version']) ?  ", benutzte Datei-Version: V " . $content['metadata']['wkvs_json_version'] : '') . ')' ]);
    unlink($destination);
    http_response_code(422);
    exit;
}

if (!isset($content['noten']) || !is_array($content['noten']) || !isset($content['disziplinen']) || !is_array($content['disziplinen'])) {
    echo json_encode(['success' => false, 'message' => 'Ungültige JSON-Struktur']);
    unlink($destination);
    http_response_code(422);
    exit;
}

$content['added_timestamp'] = date("Y-m-d H:i:s");

file_put_contents($destination, json_encode($content));

$allowedColumns = [
    'noten' => [
        'id', 'name', 'default_value', 'type', 'berechnung', 'berechnung_json', 
        'max_value', 'min_value', 'pro_geraet', 'anzahl_laeufe_json', 'geraete_json',  
        'nullstellen', 'display_string'
    ],
    'disziplinen' => ['id', 'name', 'start_index', 'color_kampfrichter', 'audiofile'],
    'zeitplan_typen' => ['id', 'name', 'has_endtime', 'display_index'],
    'leistungsklassen' => ['id', 'programm', 'order_index', 'preis', 'aktiv']
];

$tableTable = [
    'noten' => $db_tabelle_wertungstypen,
    'disziplinen' => $db_tabelle_disziplinen,
    'zeitplan_typen' => $db_tabelle_zeitplan_types,
    'leistungsklassen' => $db_tabelle_kategorien
];

$successCount = 0;

try {

    $mysqli->begin_transaction();

    foreach ($allowedColumns as $type => $columns) {

        $tableName = "`" . $tableTable[$type] . "`";

        $mysqli->query("DELETE FROM " . $tableName);

        $columnsSql = implode(', ', array_map(fn($col) => "`$col`", $columns));
        $placeholdersSql = implode(', ', array_fill(0, count($columns), '?'));

        $sql = "INSERT INTO " . $tableName . " ($columnsSql) 
                VALUES ($placeholdersSql)";

        $typesString = str_repeat('s', count($columns));

        $stmt = $mysqli->prepare($sql);

        foreach ($content[$type] as $index => $row) {
            $bindValues = [];

            foreach ($columns as $column) {
                if (!array_key_exists($column, $row) || $row[$column] === null) {
                    $bindValues[] = null;
                } else {
                    $bindValues[] = $row[$column];
                }
            }

            $stmt->bind_param($typesString, ...$bindValues);
            $stmt->execute();
            $successCount++;
        }

        $stmt->close();
    }

    $rangNote = intval($content['rang_konfiguration']['rang_note_id'] ?? 0);
    $orderBestRang = $content['rang_konfiguration']['order_best_rang'] ?? '';

    $allowableOrderValues = ['ASC', 'DESC'];

    if ($rangNote > 0) {
        $mysqli->query("INSERT INTO $db_tabelle_var (`name`, `value`) VALUES ('rangNote', '" . $rangNote . "') ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
    }

    if (in_array($orderBestRang, $allowableOrderValues, true)) {
        $mysqli->query("INSERT INTO $db_tabelle_var (`name`, `value`) VALUES ('orderBestRang', '" . $orderBestRang . "') ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
    }

    if (isset($content['bezeichnungen']['singular']) && $content['bezeichnungen']['singular'] !== null) {
        $stmt = $mysqli->prepare("INSERT INTO $db_tabelle_var (`name`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
        $varName = 'personEinzahl';
        $stmt->bind_param("ss", $varName, $content['bezeichnungen']['singular']);
        $stmt->execute();
        $stmt->close();
    }

    if (isset($content['bezeichnungen']['plural']) && $content['bezeichnungen']['plural'] !== null) {
        $stmt = $mysqli->prepare("INSERT INTO $db_tabelle_var (`name`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
        $varName = 'personMehrzahl';
        $stmt->bind_param("ss", $varName, $content['bezeichnungen']['plural']);
        $stmt->execute();
        $stmt->close();
    }
    

    $noten = db_select($mysqli, $db_tabelle_wertungstypen, "id, berechnung, type");

    $notenById = array_column($noten, null, 'id');

    $berechnungen = [];
    foreach ($notenById as $id => $sn) {
        if ($sn['type'] === 'berechnung') {
            $berechnungen[] = $sn;
        }
    }

    if (empty($berechnungen)) {
        $mysqli->commit();
        echo json_encode(['success' => true, 'message' => "Successfully imported $successCount rows."]);
        exit;
    }

    $notenRechner = new NotenRechner();

    $dependencyMap = [];

    foreach ($berechnungen as $calc) {
        $neededIdsArrayWithRun = $notenRechner->getBenoetigteIdsComplexWithRun($calc['berechnung']);
        
        if (empty($neededIdsArrayWithRun) || count($neededIdsArrayWithRun) < 2) { 
            continue; 
        }

        $calcId = (int)$calc['id'];

        $neededIdsArray = $neededIdsArrayWithRun;

        unset($neededIdsArray['targetRun']);
        unset($neededIdsArray['targetGeraet']);

        $targetRunId = $neededIdsArrayWithRun['targetRun'];

        foreach ($neededIdsArray as $key => $needed) {

            $nId = (int)$needed['noteId'];
            
            $gId = is_numeric($needed['geraetId']) ? (int)$needed['geraetId'] : $needed['geraetId'];
            
            $nodeKey = $calcId . '|' . $gId . '|' . $targetRunId;
            
            if (!isset($dependencyMap[$nId])) {
                $dependencyMap[$nId] = [];
            }
            
            $dependencyMap[$nId][$nodeKey] = [$calcId, $gId, [$targetRunId]];
        }
    }


    function getCompleteDependencyChain($id, $directMap, $visited = []) 
    {
        if (!isset($directMap[$id])) {
            return [];
        }

        $allDependencies = [];

        foreach ($directMap[$id] as $nodeKey => $complexNode) {
            if (isset($visited[$nodeKey])) {
                continue;
            }

            $visited[$nodeKey] = true;

            $allDependencies[$nodeKey] = $complexNode;

            $childDependencies = getCompleteDependencyChain($complexNode[0], $directMap, $visited);
            
            foreach ($childDependencies as $childKey => $childNode) {
                $allDependencies[$childKey] = $childNode;
                $visited[$childKey] = true;
            }
        }

        return $allDependencies;
    }

    $flatDependencyMap = [];

    foreach (array_keys($notenById) as $id) {
        $chain = getCompleteDependencyChain($id, $dependencyMap);

        if (!empty($chain)) {
            $flatDependencyMap[$id] = array_values($chain);
        }
    }

    $resetSql = "UPDATE $db_tabelle_wertungstypen SET `berechnung_json` = NULL";
    $mysqli->query($resetSql);

    // Step 2: Prepare the statement
    $updateSql = "UPDATE $db_tabelle_wertungstypen SET `berechnung_json` = ? WHERE id = ?";
    $stmt = $mysqli->prepare($updateSql);

    foreach ($flatDependencyMap as $id => $completeDependencyArray) {
        if (empty($completeDependencyArray)) {
            continue;
        }

        $jsonString = json_encode($completeDependencyArray);
        
        $stmt->bind_param("si", $jsonString, $id);
        $stmt->execute();
    }

    $stmt->close();

    $mysqli->commit();
    echo json_encode(['success' => true, 'message' => "Successfully imported $successCount rows."]);

    require_once $baseDir . '/../scripts/cache/cache-creators/regenerate-display-dependencies-cache.php';
    require_once $baseDir . '/../scripts/cache/cache-creators/regenerate-noten-cache.php';

    generateIntersectCache($mysqli, $baseDir);
    regenerate_noten_cache($mysqli, $db_tabelle_wertungstypen, $baseDir);

} catch (mysqli_sql_exception $e) {
    $mysqli->rollback();
    unlink($destination);
    
    if ($e->getCode() === 1048) {
        http_response_code(400);
        echo json_encode(['success' => false, 'message' => "Import failed: A required data field is missing in your preset file."]);
        exit;
    } else {
        http_response_code(400);
        echo json_encode(['success' => false, 'message' => "Database error during import." . " Error Code: " . $e->getMessage()]);
        exit;
    }
} finally {
    $mysqli->close();
    $allFiles = glob($uploadDir . '*.json');

    $timestamps = array_map(function($file) {
        $jsonContent = file_get_contents($file) ?? '';

        $data = json_decode($jsonContent, true) ?? [];
        
        return $data['added_timestamp'] ?? 0;
    }, $allFiles);

    array_multisort($timestamps, SORT_DESC, $allFiles);

    $filesToDelete = array_slice($allFiles, 3);

    foreach ($filesToDelete as $file) {
        unlink($file);
    }
}


