<?php
/**
 * BlogPostAI Configuration
 * Loads environment variables and provides configuration access
 */

// Load environment variables from .env file
function loadEnv($path) {
    if (!file_exists($path)) {
        return false;
    }

    $lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    foreach ($lines as $line) {
        // Skip comments
        if (strpos(trim($line), '#') === 0) {
            continue;
        }

        // Parse KEY=VALUE
        if (strpos($line, '=') !== false) {
            list($key, $value) = explode('=', $line, 2);
            $key = trim($key);
            $value = trim($value);

            // Remove quotes if present
            if (preg_match('/^(["\'])(.*)\\1$/', $value, $matches)) {
                $value = $matches[2];
            }

            if (!array_key_exists($key, $_ENV)) {
                $_ENV[$key] = $value;
                putenv("$key=$value");
            }
        }
    }
    return true;
}

// Load .env file from parent directory
$envPath = __DIR__ . '/../../.env';
loadEnv($envPath);

// Helper function to get environment variable with default
function env($key, $default = null) {
    $value = getenv($key);
    if ($value === false) {
        return $default;
    }

    // Convert string boolean to actual boolean
    if ($value === 'true') return true;
    if ($value === 'false') return false;
    if ($value === 'null') return null;

    return $value;
}

// Database Configuration
define('DB_HOST', 'db');
define('DB_NAME', 'blogpostai_db');
define('DB_USER', 'blogpostai_user');
define('DB_PASS', env('MYSQL_PASSWORD', ''));
define('DB_CHARSET', 'utf8mb4');

// Application Configuration
define('APP_ENV', env('APP_ENV', 'production'));
define('APP_DEBUG', env('APP_DEBUG', false));
define('TIMEZONE', env('TZ', 'Asia/Taipei'));

// Security Configuration
define('SESSION_TIMEOUT', (int)env('SESSION_TIMEOUT', 3600));
define('PASSWORD_MIN_LENGTH', (int)env('PASSWORD_MIN_LENGTH', 12));
define('LOGIN_MAX_ATTEMPTS', (int)env('LOGIN_MAX_ATTEMPTS', 5));
define('LOGIN_LOCKOUT_TIME', (int)env('LOGIN_LOCKOUT_TIME', 900));

// Set timezone
date_default_timezone_set(TIMEZONE);

// Database Connection Class
class Database {
    private static $instance = null;
    private $connection;

    private function __construct() {
        try {
            $dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET;
            $options = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false,
            ];

            $this->connection = new PDO($dsn, DB_USER, DB_PASS, $options);
        } catch (PDOException $e) {
            error_log("Database connection failed: " . $e->getMessage());
            if (APP_DEBUG) {
                throw $e;
            } else {
                throw new Exception("Database connection failed");
            }
        }
    }

    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function getConnection() {
        return $this->connection;
    }

    // Prevent cloning
    private function __clone() {}

    // Prevent unserialization
    public function __wakeup() {
        throw new Exception("Cannot unserialize singleton");
    }
}

// Response Helper
class Response {
    public static function json($data, $statusCode = 200) {
        http_response_code($statusCode);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

    public static function success($data = null, $message = null) {
        $response = ['success' => true];
        if ($message !== null) $response['message'] = $message;
        if ($data !== null) $response['data'] = $data;
        self::json($response);
    }

    public static function error($message, $statusCode = 400, $errors = null) {
        $response = [
            'success' => false,
            'message' => $message
        ];
        if ($errors !== null) {
            $response['errors'] = $errors;
        }
        self::json($response, $statusCode);
    }
}

// CORS Configuration
function setCorsHeaders() {
    // In production, restrict to specific origins
    $allowedOrigins = ['http://localhost:8080', 'http://10.66.88.62:8080'];

    $origin = $_SERVER['HTTP_ORIGIN'] ?? '';

    if (APP_ENV === 'development' || in_array($origin, $allowedOrigins)) {
        header('Access-Control-Allow-Origin: ' . ($origin ?: '*'));
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
        header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
    }

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

// Error Handler
function handleError($errno, $errstr, $errfile, $errline) {
    error_log("Error [$errno]: $errstr in $errfile on line $errline");

    if (APP_DEBUG) {
        Response::error("Error: $errstr", 500);
    } else {
        Response::error("An internal error occurred", 500);
    }
}

function handleException($exception) {
    error_log("Exception: " . $exception->getMessage());

    if (APP_DEBUG) {
        Response::error($exception->getMessage(), 500, [
            'file' => $exception->getFile(),
            'line' => $exception->getLine(),
            'trace' => $exception->getTraceAsString()
        ]);
    } else {
        Response::error("An internal error occurred", 500);
    }
}

// Set error handlers
set_error_handler('handleError');
set_exception_handler('handleException');

// Enable CORS
setCorsHeaders();
