<?php
require_once __DIR__ . '/db/config.php';

// This script migrates the local MariaDB database to Supabase PostgreSQL.
// It requires the Supabase Database Password.

if (php_sapi_name() !== 'cli') {
    die("This script must be run from the command line.");
}

$dbPassword = $argv[1] ?? '';
if (!$dbPassword) {
    echo "Usage: php supabase_migration.php [SUPABASE_DB_PASSWORD]\n";
    exit(1);
}

$supabaseHost = "aws-1-ap-southeast-1.pooler.supabase.com";
$supabaseUser = "postgres.siqeqnizegizxemrfgkf";
$supabaseDb = "postgres";
$supabasePort = "6543";

try {
    echo "Connecting to local MariaDB...\n";
    $localPdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);

    echo "Connecting to Supabase PostgreSQL...\n";
    $dsn = "pgsql:host=$supabaseHost;port=$supabasePort;dbname=$supabaseDb";
    $supabasePdo = new PDO($dsn, $supabaseUser, $dbPassword, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    ]);

    echo "Converting and creating tables in Supabase...\n";

    // Define tables and their PostgreSQL schemas
    $schemas = [
        "users" => "CREATE TABLE IF NOT EXISTS users (
            id VARCHAR(255) PRIMARY KEY,
            supabase_uid VARCHAR(255),
            student_id VARCHAR(10) UNIQUE NOT NULL,
            name VARCHAR(255) NOT NULL,
            email VARCHAR(255) UNIQUE NOT NULL,
            password_hash VARCHAR(255),
            grade_level INTEGER,
            track VARCHAR(100),
            section VARCHAR(100),
            role VARCHAR(50) DEFAULT 'Voter',
            access_level INTEGER DEFAULT 0,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            deleted_at TIMESTAMP
        )",
        "elections" => "CREATE TABLE IF NOT EXISTS elections (
            id VARCHAR(255) PRIMARY KEY,
            title VARCHAR(255) NOT NULL,
            description TEXT,
            status VARCHAR(50) DEFAULT 'Preparing',
            start_date_and_time TIMESTAMP NOT NULL,
            end_date_and_time TIMESTAMP NOT NULL,
            created_by VARCHAR(255) REFERENCES users(id),
            archived BOOLEAN DEFAULT FALSE,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )",
        "positions" => "CREATE TABLE IF NOT EXISTS positions (
            id VARCHAR(255) PRIMARY KEY,
            election_id VARCHAR(255) REFERENCES elections(id) ON DELETE CASCADE,
            name VARCHAR(255) NOT NULL,
            type VARCHAR(50) DEFAULT 'Uniform',
            max_votes INTEGER DEFAULT 1,
            sort_order INTEGER DEFAULT 0
        )",
        "candidates" => "CREATE TABLE IF NOT EXISTS candidates (
            id VARCHAR(255) PRIMARY KEY,
            election_id VARCHAR(255) REFERENCES elections(id) ON DELETE CASCADE,
            position_id VARCHAR(255) REFERENCES positions(id) ON DELETE CASCADE,
            user_id VARCHAR(255) REFERENCES users(id) ON DELETE CASCADE,
            party_name VARCHAR(255),
            manifesto TEXT,
            approved BOOLEAN DEFAULT FALSE,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )",
        "votes" => "CREATE TABLE IF NOT EXISTS votes (
            id VARCHAR(255) PRIMARY KEY,
            election_id VARCHAR(255) REFERENCES elections(id),
            position_id VARCHAR(255) REFERENCES positions(id),
            candidate_id VARCHAR(255) REFERENCES candidates(id),
            voter_id VARCHAR(255) REFERENCES users(id),
            casted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            ip_address VARCHAR(45),
            user_agent TEXT,
            UNIQUE (election_id, position_id, voter_id)
        )",
        "election_assignments" => "CREATE TABLE IF NOT EXISTS election_assignments (
            id VARCHAR(255) PRIMARY KEY,
            election_id VARCHAR(255) REFERENCES elections(id) ON DELETE CASCADE,
            user_id VARCHAR(255) REFERENCES users(id) ON DELETE CASCADE,
            role_in_election VARCHAR(50) DEFAULT 'Voter',
            assigned_by VARCHAR(255) REFERENCES users(id),
            assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )",
        "parties" => "CREATE TABLE IF NOT EXISTS parties (
            id VARCHAR(255) PRIMARY KEY,
            election_id VARCHAR(255) REFERENCES elections(id) ON DELETE CASCADE,
            name VARCHAR(255) NOT NULL,
            description TEXT,
            logo_url TEXT,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )",
        "audit_logs" => "CREATE TABLE IF NOT EXISTS audit_logs (
            id VARCHAR(255) PRIMARY KEY,
            user_id VARCHAR(255) REFERENCES users(id),
            action VARCHAR(255) NOT NULL,
            details TEXT,
            table_name VARCHAR(100),
            record_id VARCHAR(255),
            old_values TEXT,
            new_values TEXT,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            election_id VARCHAR(255) REFERENCES elections(id) ON DELETE CASCADE
        )"
    ];

    foreach ($schemas as $tableName => $sql) {
        echo "Creating table: $tableName...\n";
        $supabasePdo->exec($sql);
    }

    echo "Migrating data...\n";

    $tables = array_keys($schemas);
    // Order matters for foreign keys: users, elections, positions, candidates, assignments, votes, audit_logs
    $orderedTables = ["users", "elections", "positions", "election_assignments", "parties", "candidates", "votes", "audit_logs"];

    foreach ($orderedTables as $table) {
        echo "Migrating data for $table...\n";
        $stmt = $localPdo->query("SELECT * FROM $table");
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

        if (empty($rows)) {
            echo "No data for $table.\n";
            continue;
        }

        $columns = array_keys($rows[0]);
        $placeholders = implode(',', array_fill(0, count($columns), '?'));
        $insertSql = "INSERT INTO $table (" . implode(',', $columns) . ") VALUES ($placeholders) ON CONFLICT (id) DO NOTHING";
        
        $insertStmt = $supabasePdo->prepare($insertSql);
        $count = 0;
        foreach ($rows as $row) {
            $insertStmt->execute(array_values($row));
            $count++;
        }
        echo "Migrated $count rows for $table.\n";
    }

    echo "Migration completed successfully!\n";

} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
    exit(1);
}
