<?php
/**
 * Ghalla Mandi ERP — API Entry Point (Router)
 * All API requests are routed through this file via .htaccess
 */

// CORS Headers
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Idempotency-Key");
header("Content-Type: application/json; charset=utf-8");

// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

// Autoload Composer
require_once __DIR__ . '/vendor/autoload.php';

// Core Files
require_once __DIR__ . '/config/database.php';
require_once __DIR__ . '/helpers/Response.php';
require_once __DIR__ . '/helpers/Validator.php';
require_once __DIR__ . '/helpers/UUID.php';
require_once __DIR__ . '/helpers/AuditLogger.php';
require_once __DIR__ . '/services/AccountingService.php';
require_once __DIR__ . '/middleware/AuthMiddleware.php';
require_once __DIR__ . '/middleware/RBACMiddleware.php';

// Controllers
require_once __DIR__ . '/controllers/AuthController.php';
require_once __DIR__ . '/controllers/AccountController.php';
require_once __DIR__ . '/controllers/ItemController.php';
require_once __DIR__ . '/controllers/PurchaseController.php';
require_once __DIR__ . '/controllers/SaleController.php';
require_once __DIR__ . '/controllers/CashBankController.php';
require_once __DIR__ . '/controllers/ExpenseController.php';
require_once __DIR__ . '/controllers/LedgerController.php';
require_once __DIR__ . '/controllers/DashboardController.php';
require_once __DIR__ . '/controllers/UserController.php';
require_once __DIR__ . '/controllers/JournalController.php';
require_once __DIR__ . '/controllers/ReportController.php';

// ============ ROUTING ============

// Enable error logging for debugging on live server
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/error.log');

/**
 * Debug Log Helper
 */
function debug_log($message, $data = null) {
    $logFile = __DIR__ . '/error.log';
    $timestamp = date('Y-m-d H:i:s');
    $logMessage = "[$timestamp] $message";
    if ($data !== null) {
        $logMessage .= " | Data: " . json_encode($data, JSON_UNESCAPED_UNICODE);
    }
    file_put_contents($logFile, $logMessage . PHP_EOL, FILE_APPEND);
}

// Get Database Connection
$db = Database::connect();

// Parse URI: Dynamically detect base path
$scriptName = $_SERVER['SCRIPT_NAME']; // e.g., /projects/naveed_trader/api/index.php
$basePath = str_replace('/index.php', '', $scriptName);
$uri = $_GET['r'] ?? parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

// If using REQUEST_URI, we need to strip the base path
if (!isset($_GET['r']) && strpos($uri, $basePath) === 0) {
    $uri = substr($uri, strlen($basePath));
}
$uri = trim($uri, '/');

// Fallback for environments that include index.php in the path but don't support PATH_INFO
if (strpos($uri, 'index.php') === 0) {
    $uri = substr($uri, 9);
    $uri = trim($uri, '/');
}

$segments = $uri ? explode('/', $uri) : [];

// Fallback for getallheaders() if not available
if (!function_exists('getallheaders')) {
    function getallheaders() {
        $headers = [];
        foreach ($_SERVER as $name => $value) {
            if (substr($name, 0, 5) == 'HTTP_') {
                $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
            }
        }
        return $headers;
    }
}

$method = $_SERVER['REQUEST_METHOD'];
$headers = getallheaders();

// Get JSON body
$body = json_decode(file_get_contents('php://input'), true) ?? [];

// Method Spoofing Detection (for cPanel/Shared Hosting that block PUT/DELETE)
if ($method === 'POST') {
    if (isset($headers['X-HTTP-Method-Override'])) {
        $method = strtoupper($headers['X-HTTP-Method-Override']);
    } elseif (isset($body['_method'])) {
        $method = strtoupper($body['_method']);
        unset($body['_method']); // Remove it so it doesn't interfere with controllers
    }
}

// Log incoming request for debugging
debug_log("Incoming Request: $method " . $_SERVER['REQUEST_URI'], [
    'script_name' => $_SERVER['SCRIPT_NAME'],
    'base_path' => $basePath,
    'uri' => $uri,
    'segments' => $segments,
    'headers' => [
        'X-HTTP-Method-Override' => $headers['X-HTTP-Method-Override'] ?? $headers['x-http-method-override'] ?? null,
        'Authorization' => (isset($headers['Authorization']) || isset($headers['authorization'])) ? 'Present' : 'Missing'
    ],
    'body' => $body
]);

// Get query params
$query = $_GET;

try {
    // ===== PUBLIC ROUTES (No Auth Required) =====
    if (isset($segments[0]) && $segments[0] === 'auth' && isset($segments[1])) {
        $auth = new AuthController($db);
        
        if ($segments[1] === 'login' && $method === 'POST') {
            $auth->login($body);
        } elseif ($segments[1] === 'logout' && $method === 'POST') {
            $user = AuthMiddleware::authenticate($db);
            $auth->logout($user);
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // ===== AUTHENTICATED ROUTES =====
    $user = AuthMiddleware::authenticate($db);

    // Route: /accounts
    if ($segments[0] === 'accounts') {
        $ctrl = new AccountController($db, $user);
        
        if ($method === 'GET' && !isset($segments[1])) {
            $ctrl->index($query);
        } elseif ($method === 'POST' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'setup', 'create');
            $ctrl->store($body);
        } elseif ($method === 'PUT' && isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'setup', 'edit');
            $ctrl->update((int)$segments[1], $body);
        } elseif ($method === 'DELETE' && isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'setup', 'edit');
            $ctrl->destroy((int)$segments[1]);
        } elseif ($method === 'POST' && isset($segments[1]) && isset($segments[2]) && $segments[2] === 'renew-alert') {
            RBACMiddleware::check($db, $user, 'setup', 'edit');
            $ctrl->renewAlert((int)$segments[1]);
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /items
    if ($segments[0] === 'items') {
        $ctrl = new ItemController($db, $user);
        
        if ($method === 'GET' && !isset($segments[1])) {
            $ctrl->index($query);
        } elseif ($method === 'POST' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'setup', 'create');
            $ctrl->store($body);
        } elseif ($method === 'PUT' && isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'setup', 'edit');
            $ctrl->update((int)$segments[1], $body);
        } elseif ($method === 'DELETE' && isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'setup', 'edit');
            $ctrl->destroy((int)$segments[1]);
        } elseif ($method === 'GET' && isset($segments[1]) && isset($segments[2]) && $segments[2] === 'advanced-ledger') {
            RBACMiddleware::check($db, $user, 'ledger', 'view');
            $ctrl->advancedLedger((int)$segments[1], $query);
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /purchases
    if ($segments[0] === 'purchases') {
        $ctrl = new PurchaseController($db, $user);
        
        if (isset($segments[1]) && $segments[1] === 'next-voucher' && $method === 'GET') {
            $ctrl->nextVoucher();
        } elseif ($method === 'GET' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'purchase', 'view');
            $ctrl->index($query);
        } elseif ($method === 'GET' && isset($segments[1]) && !isset($segments[2])) {
            RBACMiddleware::check($db, $user, 'purchase', 'view');
            $ctrl->show((int)$segments[1]);
        } elseif ($method === 'POST' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'purchase', 'create');
            $ctrl->store($body);
        } elseif ($method === 'PUT' && isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'purchase', 'edit');
            $ctrl->update((int)$segments[1], $body);
        } elseif ($method === 'POST' && isset($segments[1]) && isset($segments[2]) && $segments[2] === 'reverse') {
            RBACMiddleware::check($db, $user, 'purchase', 'delete');
            $ctrl->reverse((int)$segments[1]);
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /sales
    if ($segments[0] === 'sales') {
        $ctrl = new SaleController($db, $user);
        
        if (isset($segments[1]) && $segments[1] === 'next-voucher' && $method === 'GET') {
            $ctrl->nextVoucher();
        } elseif ($method === 'GET' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'sale', 'view');
            $ctrl->index($query);
        } elseif ($method === 'GET' && isset($segments[1]) && !isset($segments[2])) {
            RBACMiddleware::check($db, $user, 'sale', 'view');
            $ctrl->show((int)$segments[1]);
        } elseif ($method === 'POST' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'sale', 'create');
            $ctrl->store($body);
        } elseif ($method === 'PUT' && isset($segments[1]) && !isset($segments[2])) {
            RBACMiddleware::check($db, $user, 'sale', 'edit');
            $ctrl->update((int)$segments[1], $body);
        } elseif ($method === 'POST' && isset($segments[1]) && isset($segments[2]) && $segments[2] === 'reverse') {
            RBACMiddleware::check($db, $user, 'sale', 'delete');
            $ctrl->reverse((int)$segments[1]);
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /lots
    if ($segments[0] === 'lots') {
        $ctrl = new PurchaseController($db, $user);
        
        if ($method === 'GET') {
            RBACMiddleware::check($db, $user, 'sale', 'view');
            $ctrl->lots($query);
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /cash-bank
    if ($segments[0] === 'cash-bank') {
        $ctrl = new CashBankController($db, $user);
        
        if ($method === 'GET' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'cashBank', 'view');
            $ctrl->index($query);
        } elseif ($method === 'POST' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'cashBank', 'create');
            $ctrl->store($body);
        } elseif ($method === 'POST' && isset($segments[1]) && isset($segments[2]) && $segments[2] === 'reverse') {
            RBACMiddleware::check($db, $user, 'cashBank', 'delete');
            $ctrl->reverse((int)$segments[1]);
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /expenses
    if ($segments[0] === 'expenses') {
        $ctrl = new ExpenseController($db, $user);
        
        if ($method === 'GET' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'expense', 'view');
            $ctrl->index($query);
        } elseif ($method === 'POST' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'expense', 'create');
            $ctrl->store($body);
        } elseif ($method === 'PUT' && isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'expense', 'edit');
            $ctrl->update((int)$segments[1], $body);
        } elseif ($method === 'DELETE' && isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'expense', 'delete');
            $ctrl->destroy((int)$segments[1]);
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /ledger/{account_id}
    if ($segments[0] === 'ledger') {
        $ctrl = new LedgerController($db, $user);
        
        if ($method === 'GET' && isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'ledger', 'view');
            if (isset($segments[2]) && $segments[2] === 'balance') {
                $ctrl->balance((int)$segments[1]);
            } else {
                $ctrl->show((int)$segments[1], $query);
            }
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /dashboard
    if ($segments[0] === 'dashboard') {
        $ctrl = new DashboardController($db, $user);
        
        if ($method === 'GET' && isset($segments[1]) && $segments[1] === 'stats') {
            $ctrl->stats();
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /users
    if ($segments[0] === 'users') {
        $ctrl = new UserController($db, $user);
        
        if ($method === 'GET' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'users', 'view');
            $ctrl->index();
        } elseif ($method === 'GET' && isset($segments[1]) && $segments[1] === 'me') {
            $ctrl->me();
        } elseif ($method === 'POST' && !isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'users', 'create');
            $ctrl->store($body);
        } elseif ($method === 'PUT' && isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'users', 'edit');
            $ctrl->update((int)$segments[1], $body);
        } elseif ($method === 'DELETE' && isset($segments[1])) {
            RBACMiddleware::check($db, $user, 'users', 'delete');
            $ctrl->destroy((int)$segments[1]);
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /journals
    if ($segments[0] === 'journals') {
        $ctrl = new JournalController($db, $user);
        
        if ($method === 'POST') {
            RBACMiddleware::check($db, $user, 'ledger', 'create');
            if (isset($segments[1]) && $segments[1] === 'add-capital') {
                $ctrl->addCapital($body);
            } else {
                $ctrl->store($body);
            }
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // Route: /reports
    if ($segments[0] === 'reports') {
        $ctrl = new ReportController($db, $user);
        
        if ($method === 'GET' && isset($segments[1]) && $segments[1] === 'financial-summary') {
            RBACMiddleware::check($db, $user, 'ledger', 'view'); // Using ledger view permission for now
            $ctrl->financialSummary();
        } else {
            Response::error('Route not found', 404);
        }
        exit;
    }

    // No route matched
    Response::error('Endpoint not found', 404);

} catch (Exception $e) {
    debug_log("API Error: " . $e->getMessage(), ['trace' => $e->getTraceAsString()]);
    $code = $e->getCode() ?: 500;
    if ($code < 100 || $code > 599) $code = 500;
    Response::error($e->getMessage(), $code);
}
