<?php
// ================================================
// engine.php - Full Updated Version
// Instagram Archive Backend (PHP + MySQL)
// Supports: Upload ZIP, Load data.zip, AND Import entire source-files folder
// ================================================

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Content-Type');

$host = 'localhost';
$db   = 'tasmoybb_grammie';
$user = 'tasmoybb_grammie';
$pass = '3XT3RN4l!337';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
    echo json_encode(['success' => false, 'message' => 'Database connection failed: ' . $e->getMessage()]);
    exit;
}

// Create necessary tables
function createTables($pdo) {
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS profile (
            id INT AUTO_INCREMENT PRIMARY KEY,
            username VARCHAR(255),
            full_name VARCHAR(255),
            bio TEXT,
            profile_pic VARCHAR(500),
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
        ) ENGINE=InnoDB;
    ");

    $pdo->exec("
        CREATE TABLE IF NOT EXISTS following (
            id INT AUTO_INCREMENT PRIMARY KEY,
            username VARCHAR(255) UNIQUE,
            added_at DATETIME DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB;
    ");

    $pdo->exec("
        CREATE TABLE IF NOT EXISTS followers (
            id INT AUTO_INCREMENT PRIMARY KEY,
            username VARCHAR(255) UNIQUE,
            added_at DATETIME DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB;
    ");

    $pdo->exec("
        CREATE TABLE IF NOT EXISTS posts (
            id INT AUTO_INCREMENT PRIMARY KEY,
            media_path VARCHAR(500),
            media_type ENUM('image', 'video'),
            caption TEXT,
            timestamp BIGINT,
            added_at DATETIME DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB;
    ");

    $pdo->exec("
        CREATE TABLE IF NOT EXISTS messages (
            id INT AUTO_INCREMENT PRIMARY KEY,
            conversation_title VARCHAR(500),
            message_count INT,
            last_timestamp BIGINT,
            added_at DATETIME DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB;
    ");
}

createTables($pdo);

$action = $_GET['action'] ?? $_POST['action'] ?? '';

switch ($action) {

    // ====================== UPLOAD NEW ZIP ======================
    case 'upload_zip':
        if (!isset($_FILES['zip']) || $_FILES['zip']['error'] !== UPLOAD_ERR_OK) {
            echo json_encode(['success' => false, 'message' => 'No valid ZIP file uploaded']);
            exit;
        }

        $zipFile = $_FILES['zip']['tmp_name'];
        $tempDir = sys_get_temp_dir() . '/ig_import_' . uniqid();
        mkdir($tempDir, 0777, true);

        $zip = new ZipArchive();
        if ($zip->open($zipFile) !== TRUE) {
            echo json_encode(['success' => false, 'message' => 'Failed to open ZIP file']);
            exit;
        }

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

        // Copy media files to public folder
        copyMediaFiles($tempDir, $_SERVER['DOCUMENT_ROOT'] . '/instagram_export');

        importFromFolder($pdo, $tempDir);

        deleteDirectory($tempDir);

        echo json_encode(['success' => true, 'message' => 'ZIP uploaded, media copied, and data imported successfully']);
        break;

    // ====================== LOAD FROM source-files/data.zip ======================
    case 'load_server_data':
        $serverZipPath = __DIR__ . '/source-files/data.zip';

        if (!file_exists($serverZipPath)) {
            echo json_encode(['success' => false, 'message' => 'data.zip not found in source-files folder']);
            exit;
        }

        $tempDir = sys_get_temp_dir() . '/ig_server_import_' . uniqid();
        mkdir($tempDir, 0777, true);

        $zip = new ZipArchive();
        if ($zip->open($serverZipPath) !== TRUE) {
            echo json_encode(['success' => false, 'message' => 'Failed to open data.zip']);
            exit;
        }

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

        copyMediaFiles($tempDir, $_SERVER['DOCUMENT_ROOT'] . '/instagram_export');
        importFromFolder($pdo, $tempDir);

        deleteDirectory($tempDir);

        echo json_encode(['success' => true, 'message' => 'data.zip loaded and imported successfully']);
        break;

    // ====================== NEW: IMPORT EVERYTHING FROM source-files FOLDER ======================
    case 'import_source_folder':
        $sourceDir = __DIR__ . '/source-files';
        
        if (!is_dir($sourceDir)) {
            echo json_encode(['success' => false, 'message' => 'source-files folder does not exist']);
            exit;
        }

        $mediaTarget = $_SERVER['DOCUMENT_ROOT'] . '/instagram_export';
        if (!is_dir($mediaTarget)) {
            mkdir($mediaTarget, 0777, true);
        }

        // Copy all media files (images & videos) from source-files to public folder
        copyMediaFiles($sourceDir, $mediaTarget);

        // Import JSON data from source-files (including all subfolders)
        importFromFolder($pdo, $sourceDir);

        echo json_encode(['success' => true, 'message' => 'All files and media from source-files folder imported successfully']);
        break;

    // ====================== GET PROFILE ======================
    case 'get_profile':
        $stmt = $pdo->query("SELECT * FROM profile ORDER BY id DESC LIMIT 1");
        $profile = $stmt->fetch();
        echo json_encode($profile ?: ['username' => '', 'full_name' => '', 'bio' => '', 'profile_pic' => '']);
        break;

    // ====================== GET FOLLOWING ======================
    case 'get_following':
        $stmt = $pdo->query("SELECT username FROM following ORDER BY username");
        $following = $stmt->fetchAll(PDO::FETCH_COLUMN);
        echo json_encode(['following' => $following]);
        break;

    // ====================== GET FOLLOWERS ======================
    case 'get_followers':
        $stmt = $pdo->query("SELECT username FROM followers ORDER BY username");
        $followers = $stmt->fetchAll(PDO::FETCH_COLUMN);
        echo json_encode(['followers' => $followers]);
        break;

    // ====================== GET NON-FOLLOWERS ======================
    case 'get_non_followers':
        $stmt = $pdo->query("
            SELECT f.username 
            FROM following f 
            LEFT JOIN followers fol ON f.username = fol.username 
            WHERE fol.username IS NULL 
            ORDER BY f.username
        ");
        $non = $stmt->fetchAll(PDO::FETCH_COLUMN);
        echo json_encode(['non_followers' => $non]);
        break;

    // ====================== GET POSTS ======================
    case 'get_posts':
        $stmt = $pdo->query("SELECT media_path, media_type, caption, timestamp FROM posts ORDER BY timestamp DESC");
        $posts = $stmt->fetchAll();
        echo json_encode(['posts' => $posts]);
        break;

    // ====================== GET MESSAGES ======================
    case 'get_messages':
        $stmt = $pdo->query("SELECT conversation_title, message_count, last_timestamp FROM messages ORDER BY last_timestamp DESC");
        $msgs = $stmt->fetchAll();
        echo json_encode(['messages' => $msgs]);
        break;

    default:
        echo json_encode(['success' => false, 'message' => 'Invalid action']);
}

// ====================== CORE IMPORT FUNCTION ======================
function importFromFolder($pdo, $rootDir) {
    // Clear previous data (uncomment if you want to keep history instead)
    $pdo->exec("TRUNCATE TABLE profile");
    $pdo->exec("TRUNCATE TABLE following");
    $pdo->exec("TRUNCATE TABLE followers");
    $pdo->exec("TRUNCATE TABLE posts");
    $pdo->exec("TRUNCATE TABLE messages");

    // 1. PROFILE
    $profileFiles = array_merge(
        glob($rootDir . '/*profile*.json'),
        glob($rootDir . '/*/profile*.json'),
        glob($rootDir . '/personal_information/*.json')
    );

    foreach ($profileFiles as $file) {
        $json = json_decode(file_get_contents($file), true);
        if (is_array($json)) {
            $user = $json['profile_user'] ?? $json['user'] ?? $json ?? [];
            $username = $user['username'] ?? '';
            $fullName = $user['full_name'] ?? '';
            $bio = $user['biography'] ?? $user['bio'] ?? '';
            $pic = $user['profile_picture_uri'] ?? $user['profile_pic_url'] ?? '';

            if ($username) {
                $stmt = $pdo->prepare("INSERT INTO profile (username, full_name, bio, profile_pic) VALUES (?, ?, ?, ?)");
                $stmt->execute([$username, $fullName, $bio, $pic]);
                break;
            }
        }
    }

    // 2. FOLLOWING
    $followingFiles = array_merge(
        glob($rootDir . '/*following*.json'),
        glob($rootDir . '/*/following*.json')
    );
    foreach ($followingFiles as $file) {
        $json = json_decode(file_get_contents($file), true);
        if (isset($json['relationships_following']) && is_array($json['relationships_following'])) {
            foreach ($json['relationships_following'] as $item) {
                if (isset($item['string_list_data'][0]['value'])) {
                    $username = $item['string_list_data'][0]['value'];
                    $stmt = $pdo->prepare("INSERT IGNORE INTO following (username) VALUES (?)");
                    $stmt->execute([$username]);
                }
            }
        }
    }

    // 3. FOLLOWERS
    $followerFiles = array_merge(
        glob($rootDir . '/*followers*.json'),
        glob($rootDir . '/*/followers*.json')
    );
    foreach ($followerFiles as $file) {
        $json = json_decode(file_get_contents($file), true);
        if (isset($json['relationships_followers']) && is_array($json['relationships_followers'])) {
            foreach ($json['relationships_followers'] as $item) {
                if (isset($item['string_list_data'][0]['value'])) {
                    $username = $item['string_list_data'][0]['value'];
                    $stmt = $pdo->prepare("INSERT IGNORE INTO followers (username) VALUES (?)");
                    $stmt->execute([$username]);
                }
            }
        }
    }

    // 4. POSTS
    $postFiles = array_merge(
        glob($rootDir . '/posts_*.json'),
        glob($rootDir . '/*/posts_*.json'),
        glob($rootDir . '/your_posts/*.json')
    );
    foreach ($postFiles as $file) {
        $json = json_decode(file_get_contents($file), true);
        $postsArray = $json['posts'] ?? (is_array($json) ? $json : []);

        if (is_array($postsArray)) {
            foreach ($postsArray as $postGroup) {
                $mediaList = $postGroup['media'] ?? [$postGroup];
                foreach ($mediaList as $media) {
                    if (isset($media['uri'])) {
                        $mediaPath = $media['uri'];
                        $mediaType = str_ends_with(strtolower($mediaPath), '.mp4') ? 'video' : 'image';
                        $caption = $media['caption'] ?? $media['title'] ?? '';
                        $timestamp = $media['creation_timestamp'] ?? $media['taken_at'] ?? time();

                        $stmt = $pdo->prepare("INSERT INTO posts (media_path, media_type, caption, timestamp) VALUES (?, ?, ?, ?)");
                        $stmt->execute([$mediaPath, $mediaType, $caption, $timestamp]);
                    }
                }
            }
        }
    }

    // 5. MESSAGES
    $msgFiles = glob($rootDir . '/messages/inbox/*/message_*.json');
    foreach ($msgFiles as $file) {
        $json = json_decode(file_get_contents($file), true);
        if (isset($json['messages']) && is_array($json['messages']) && count($json['messages']) > 0) {
            $title = basename(dirname($file));
            $count = count($json['messages']);
            $lastTs = $json['messages'][0]['timestamp_ms'] ?? 0;
            if ($lastTs > 0) $lastTs = (int)($lastTs / 1000);

            $stmt = $pdo->prepare("INSERT INTO messages (conversation_title, message_count, last_timestamp) VALUES (?, ?, ?)");
            $stmt->execute([$title, $count, $lastTs]);
        }
    }
}

// ====================== COPY MEDIA FILES RECURSIVELY ======================
function copyMediaFiles($source, $destination) {
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($iterator as $item) {
        if ($item->isFile()) {
            $ext = strtolower(pathinfo($item->getFilename(), PATHINFO_EXTENSION));
            if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'mp4', 'mov', 'webp', 'heic'])) {
                $relativePath = substr($item->getPathname(), strlen($source) + 1);
                $targetPath = $destination . '/' . $relativePath;
                
                $targetDir = dirname($targetPath);
                if (!is_dir($targetDir)) {
                    mkdir($targetDir, 0777, true);
                }
                
                copy($item->getPathname(), $targetPath);
            }
        }
    }
}

// ====================== DELETE TEMP DIRECTORY ======================
function deleteDirectory($dir) {
    if (!file_exists($dir)) return;
    $files = array_diff(scandir($dir), ['.', '..']);
    foreach ($files as $file) {
        (is_dir("$dir/$file")) ? deleteDirectory("$dir/$file") : unlink("$dir/$file");
    }
    return rmdir($dir);
}

echo json_encode(['success' => false, 'message' => 'No action specified']);
?>