<?php
// import.php

header('Content-Type: application/json; charset=utf-8');

$config = require __DIR__ . '/config.php';

// ================= HELPERS =================
function respond(array $data, int $code = 200): void {
    http_response_code($code);
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

function error_response(string $msg, int $code = 400): void {
    respond(['success' => false, 'error' => $msg], $code);
}

// ================= CONFIG =================
$db     = $config['db'];
$paths  = $config['paths'];
$debug  = (bool)($config['app']['debug'] ?? false);

$assetsDir  = rtrim($paths['assets'], '/') . '/';
$importsDir = rtrim($paths['imports'], '/') . '/';

// ================= DB =================
$conn = new mysqli($db['host'], $db['user'], $db['pass'], $db['name']);
if ($conn->connect_error) {
    error_response('Database connection failed', 500);
}
$conn->set_charset($db['charset']);

// ================= ZIP SOURCE =================
$localMode = isset($_GET['local']);

if ($localMode) {
    $zipPath = $importsDir . 'data.zip';
    if (!is_file($zipPath)) {
        error_response('No local ZIP found');
    }
} else {
    if ($_SERVER['REQUEST_METHOD'] !== 'POST' || empty($_FILES['data_zip'])) {
        error_response('No file uploaded');
    }

    $file = $_FILES['data_zip'];

    if ($file['error'] !== UPLOAD_ERR_OK) {
        error_response('Upload error');
    }

    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mime  = $finfo->file($file['tmp_name']);

    if ($mime !== 'application/zip') {
        error_response('Invalid ZIP file');
    }

    $zipPath = $file['tmp_name'];
}

// ================= SAFE ASSETS RESET =================
$realAssets = realpath($assetsDir) ?: $assetsDir;

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

if (strpos(realpath($realAssets), realpath(__DIR__)) !== 0) {
    error_response('Unsafe assets path', 500);
}

$it = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($realAssets, FilesystemIterator::SKIP_DOTS),
    RecursiveIteratorIterator::CHILD_FIRST
);

foreach ($it as $file) {
    $file->isDir() ? rmdir($file->getRealPath()) : unlink($file->getRealPath());
}

// ================= ZIP EXTRACTION (SAFE) =================
$zip = new ZipArchive();
if ($zip->open($zipPath) !== true) {
    error_response('Failed to open ZIP');
}

for ($i = 0; $i < $zip->numFiles; $i++) {
    $name = $zip->getNameIndex($i);

    if (str_contains($name, '..')) {
        $zip->close();
        error_response('Unsafe ZIP contents');
    }
}

$zip->extractTo($realAssets);
$zip->close();

// ================= PARSE JSON =================
$connDir = $realAssets . 'connections/followers_and_following/';
$followingFiles = is_dir($connDir) ? glob($connDir . '*following*.json') : [];
$followersFiles = is_dir($connDir) ? glob($connDir . '*followers*.json') : [];

$conn->begin_transaction();

try {
    $conn->query("TRUNCATE TABLE accounts");

    $followingData = [];
    foreach ($followingFiles as $path) {
        $json = json_decode(file_get_contents($path), true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new RuntimeException('Invalid following JSON');
        }

        foreach ($json['relationships_following'] ?? [] as $entry) {
            $sld = $entry['string_list_data'][0] ?? null;
            if (!$sld || empty($sld['value'])) continue;

            $followingData[$sld['value']] = [
                'href' => $sld['href'] ?? '',
                'ts'   => (int)($sld['timestamp'] ?? 0)
            ];
        }
    }

    $followersData = [];
    foreach ($followersFiles as $path) {
        $json = json_decode(file_get_contents($path), true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new RuntimeException('Invalid followers JSON');
        }

        foreach ($json as $entry) {
            $sld = $entry['string_list_data'][0] ?? null;
            if (!$sld || empty($sld['value'])) continue;

            $followersData[$sld['value']] = [
                'href' => $sld['href'] ?? '',
                'ts'   => (int)($sld['timestamp'] ?? 0)
            ];
        }
    }

    $stmt = $conn->prepare("
        INSERT INTO accounts
        (username, href, timestamp, is_following, is_followed_by)
        VALUES (?, ?, ?, ?, ?)
    ");

    foreach (array_unique(array_merge(array_keys($followingData), array_keys($followersData))) as $username) {
        $isFollowing   = isset($followingData[$username]) ? 1 : 0;
        $isFollowedBy  = isset($followersData[$username]) ? 1 : 0;
        $href = $followingData[$username]['href']
             ?? $followersData[$username]['href']
             ?? '';
        $ts   = $followingData[$username]['ts']
             ?? $followersData[$username]['ts']
             ?? 0;

        $stmt->bind_param('ssiii', $username, $href, $ts, $isFollowing, $isFollowedBy);
        $stmt->execute();
    }

    $stmt->close();
    $conn->commit();

} catch (Throwable $e) {
    $conn->rollback();
    error_response($debug ? $e->getMessage() : 'Import failed', 500);
}

$conn->close();

respond([
    'success' => true,
    'message' => '✅ Backup imported successfully. Data is now available.'
]);