<?php
// api/installer.php
// Handles database initialization, config writing, and admin creation

header('Content-Type: application/json');

// Check if already installed
if (file_exists('../.installed')) {
    echo json_encode(['success' => false, 'message' => 'System already installed. Please remove .installed to reinstall.']);
    exit;
}

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

if ($action === 'test_db') {
    $host = $_POST['db_host'] ?? '';
    $name = $_POST['db_name'] ?? '';
    $user = $_POST['db_user'] ?? '';
    $pass = $_POST['db_pass'] ?? '';

    try {
        $pdo = new PDO("mysql:host=$host;dbname=$name;charset=utf8", $user, $pass);
        
        // Check for existing tables to decide if we should show analyzer
        $stmt = $pdo->query("SHOW TABLES");
        $tables = $stmt->fetchAll(PDO::FETCH_COLUMN);
        
        echo json_encode([
            'success' => true, 
            'has_existing_data' => count($tables) > 0,
            'table_count' => count($tables)
        ]);
    } catch (PDOException $e) {
        echo json_encode(['success' => false, 'message' => 'Connection failed: ' . $e->getMessage()]);
    }

} elseif ($action === 'analyze_db') {
    $host = $_POST['db_host'] ?? '';
    $name = $_POST['db_name'] ?? '';
    $user = $_POST['db_user'] ?? '';
    $pass = $_POST['db_pass'] ?? '';

    try {
        $pdo = new PDO("mysql:host=$host;dbname=$name;charset=utf8", $user, $pass);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // 1. Get Existing Schema
        $existingSchema = [];
        $stmt = $pdo->query("SHOW TABLES");
        while ($table = $stmt->fetch(PDO::FETCH_COLUMN)) {
            $colStmt = $pdo->query("SHOW COLUMNS FROM `$table` ");
            $cols = $colStmt->fetchAll(PDO::FETCH_COLUMN);
            $existingSchema[$table] = $cols;
        }

        // 2. Parse database.sql for Expected Schema
        $sql = file_get_contents('../database.sql');
        $expectedSchema = [];
        
        // Simplified parsing for CREATE TABLE
        preg_match_all('/CREATE TABLE `([^`]+)` \((.*?)\) ENGINE/s', $sql, $matches);
        foreach ($matches[1] as $index => $tableName) {
            $tableDef = $matches[2][$index];
            preg_match_all('/`([^`]+)`/', $tableDef, $colMatches);
            // First few matches might be columns, then indexes
            // We only care about the columns in the main definition block
            $expectedSchema[$tableName] = array_unique($colMatches[1]);
        }

        // 3. Compare
        $analysis = [
            'missing_tables' => [],
            'missing_columns' => [],
            'is_legacy' => false
        ];

        foreach ($expectedSchema as $table => $cols) {
            if (!isset($existingSchema[$table])) {
                $analysis['missing_tables'][] = $table;
                $analysis['is_legacy'] = true;
            } else {
                foreach ($cols as $col) {
                    // Filter out indices and keywords
                    if (in_array(strtoupper($col), ['PRIMARY', 'KEY', 'UNIQUE', 'CONSTRAINT', 'FOREIGN'])) continue;
                    
                    if (!in_array($col, $existingSchema[$table])) {
                        $analysis['missing_columns'][] = "$table.$col";
                        $analysis['is_legacy'] = true;
                    }
                }
            }
        }

        echo json_encode(['success' => true, 'analysis' => $analysis]);
    } catch (Exception $e) {
        echo json_encode(['success' => false, 'message' => 'Analysis failed: ' . $e->getMessage()]);
    }

} elseif ($action === 'install') {
    $host = $_POST['db_host'] ?? '';
    $db_name = $_POST['db_name'] ?? '';
    $db_user = $_POST['db_user'] ?? '';
    $db_pass = $_POST['db_pass'] ?? '';
    
    $comp_name = $_POST['company_name'] ?? 'JUSTSALE';
    $curr_code = $_POST['currency_code'] ?? 'USD';
    $curr_name = $_POST['currency_name'] ?? 'US Dollar';
    
    $admin_full = $_POST['admin_fullname'] ?? 'Administrator';
    $admin_user = $_POST['admin_user'] ?? 'admin';
    $admin_pass = $_POST['admin_pass'] ?? '';

    if (empty($admin_pass)) {
        echo json_encode(['success' => false, 'message' => 'Admin password is required.']);
        exit;
    }

    try {
        $pdo = new PDO("mysql:host=$host;dbname=$db_name;charset=utf8", $db_user, $db_pass);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // 0. Disable foreign key checks for existing DB installation
        $pdo->exec("SET FOREIGN_KEY_CHECKS = 0;");

        // 1. Analyze Core Tables & Columns (Smart Analysis)
        $existingTables = [];
        $stmt = $pdo->query("SHOW TABLES");
        while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
            $existingTables[] = $row[0];
        }

        $sql = file_get_contents('../database.sql');

        // Dynamic SQL Rewriter: Use IF NOT EXISTS for tables and IGNORE for inserts
        $sql = str_replace('CREATE TABLE `', 'CREATE TABLE IF NOT EXISTS `', $sql);
        $sql = str_replace('INSERT INTO `', 'INSERT IGNORE INTO `', $sql);

        // Split SQL into individual statements for granular execution
        $statements = explode(";\n", $sql);
        foreach ($statements as $query) {
            $query = trim($query);
            if (empty($query)) continue;
            try {
                $pdo->exec($query);
            } catch (PDOException $e) {
                // Ignore "Table already exists", "Duplicate column", "Duplicate key"
                if (strpos($e->getMessage(), '1050') !== false || 
                    strpos($e->getMessage(), '1060') !== false || 
                    strpos($e->getMessage(), '1061') !== false || 
                    strpos($e->getMessage(), '1062') !== false || 
                    strpos($e->getMessage(), '1068') !== false ||
                    strpos($e->getMessage(), '1826') !== false ||
                    strpos($e->getMessage(), '1022') !== false) {
                    continue; 
                }
                throw $e; // Rethrow actual errors
            }
        }

        // 2. Column-Level Migration (Advanced Seamless Update)
        // Ensure all v3.0 Specific columns exist in potential legacy tables
        $migrations = [
            'users' => [
                'printing_method' => "ALTER TABLE `users` ADD COLUMN `printing_method` enum('Browser','LocalService','MobilePOS') NOT NULL DEFAULT 'Browser' ",
                'short_details' => "ALTER TABLE `users` ADD COLUMN `short_details` text DEFAULT NULL AFTER `photo` "
            ],
            'products' => [
                'track_batches' => "ALTER TABLE `products` ADD COLUMN `track_batches` tinyint(1) DEFAULT 0 AFTER `min_stock_level` "
            ],
            'sale_items' => [
                'batch_id' => "ALTER TABLE `sale_items` ADD COLUMN `batch_id` int(11) DEFAULT NULL AFTER `subtotal` "
            ],
            'reception_items' => [
                'batch_id' => "ALTER TABLE `reception_items` ADD COLUMN `batch_id` int(11) DEFAULT NULL AFTER `quantity_received` "
            ],
            'stock_adjustments' => [
                'batch_id' => "ALTER TABLE `stock_adjustments` ADD COLUMN `batch_id` int(11) DEFAULT NULL AFTER `user_id` "
            ]
        ];

        foreach ($migrations as $table => $cols) {
            if (in_array($table, $existingTables)) {
                $check = $pdo->query("SHOW COLUMNS FROM `$table` ");
                $tableCols = [];
                while($c = $check->fetch()) { $tableCols[] = $c['Field']; }
                
                foreach ($cols as $col => $query) {
                    if (!in_array($col, $tableCols)) {
                        $pdo->exec($query);
                    }
                }
            }
        }

        // RE-ENABLE checks
        $pdo->exec("SET FOREIGN_KEY_CHECKS = 1;");

        // 2. Clear dummy settings and apply user settings
        $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)")
             ->execute(['company_name', $comp_name]);
        $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)")
             ->execute(['company_currency_code', $curr_code]);
        $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)")
             ->execute(['company_currency_name', $curr_name]);
        $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)")
             ->execute(['system_version', '3.0.0']);

        // 3. Create/Update Admin User
        $hash = password_hash($admin_pass, PASSWORD_DEFAULT);
        $stmt = $pdo->prepare("INSERT INTO users (username, fullname, password_hash, role) VALUES (?, ?, ?, 'Admin') ON DUPLICATE KEY UPDATE password_hash = VALUES(password_hash), fullname = VALUES(fullname)");
        $stmt->execute([$admin_user, $admin_full, $hash]);

        // 4. Write api/db.php with isLocal detection logic
        $db_content = "<?php
// api/db.php - Generated by Setup Wizard
define('SYSTEM_VERSION', '3.0.0');
\$isLocal = false;
if (PHP_SAPI === 'cli' || !isset(\$_SERVER['SERVER_NAME'])) {
    \$isLocal = true;
} else {
    \$server = \$_SERVER['SERVER_NAME'];
    if (\$server === 'localhost' || \$server === '127.0.0.1' || strpos(\$server, '192.168.') === 0 || strpos(\$server, '10.') === 0 || strpos(\$server, '172.') === 0) {
        \$isLocal = true;
    }
}

if (\$isLocal) {
    \$host = 'localhost';
    \$dbname = '$db_name'; 
    \$username = 'root';
    \$password = '';
} else {
    \$host = '$host';
    \$dbname = '$db_name';
    \$username = '$db_user';
    \$password = '$db_pass'; 
}

try {
    \$pdo = new PDO(\"mysql:host=\$host;dbname=\$dbname;charset=utf8\", \$username, \$password);
    \$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    \$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException \$e) {
    header('Content-Type: application/json');
    die(json_encode(['success' => false, 'message' => 'Database connection failed.']));
}

// Licensing Gatekeeper
require_once 'license_check_middleware.php';
";
        file_put_contents('db.php', $db_content);

        // 5. Create Lock file
        file_put_contents('../.installed', date('Y-m-d H:i:s'));

        echo json_encode(['success' => true]);

    } catch (Exception $e) {
        echo json_encode(['success' => false, 'message' => 'Installation failed: ' . $e->getMessage()]);
    }
}
