<?php
/**
 * fetch-company-settings.php - API endpoint for fetching company settings
 * 
 * MEMBERS PORTAL - Fetch company configuration only
 * 
 * @package CreativeMembersPortal
 * @version 1.0.0
 */

// ============================================
// INITIALIZATION
// ============================================

// Error handling configuration
error_reporting(E_ALL);
ini_set('display_errors', 0); // Don't display errors to users

// Load CORS configuration FIRST
require_once __DIR__ . '/includes/cors.php';
configureCors();

// Load environment variables
require_once __DIR__ . '/includes/config_loader.php';

// Load dependencies
require_once __DIR__ . '/includes/config.php';
require_once __DIR__ . '/includes/auth_functions.php';
require_once __DIR__ . '/auth/AuditLogger.php';
require_once __DIR__ . '/auth/JWTManager.php';

// Set response headers
header('Content-Type: application/json');
header('Cache-Control: no-cache, private, max-age=300'); // 5 minutes cache
header('Pragma: no-cache');
header('Expires: 0');

// Add security headers
header('X-Frame-Options: DENY');
header('X-Content-Type-Options: nosniff');
header('X-XSS-Protection: 1; mode=block');
header('Referrer-Policy: strict-origin-when-cross-origin');

// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    header('Access-Control-Max-Age: 86400');
    header('Content-Length: 0');
    http_response_code(200);
    exit();
}

// Start session with secure configuration
if (session_status() === PHP_SESSION_NONE) {
    session_name('MEMBER_PORTAL_SESSION');
    session_set_cookie_params([
        'lifetime' => 0,
        'path' => '/',
        'domain' => $_SERVER['HTTP_HOST'] ?? '',
        'secure' => true,
        'httponly' => true,
        'samesite' => 'Lax'
    ]);
    
    session_start();
    
    // Regenerate ID periodically
    if (empty($_SESSION['session_regenerated'])) {
        session_regenerate_id(true);
        $_SESSION['session_regenerated'] = time();
    }
}

// Request deduplication and tracking
$requestId = uniqid('settings_', true);
$_SERVER['REQUEST_TIME_FLOAT'] = $_SERVER['REQUEST_TIME_FLOAT'] ?? microtime(true);

error_log("[$requestId] === FETCH COMPANY SETTINGS REQUEST START ===");

// Initialize Audit Logger
try {
    $auditLogger = new AuditLogger($pdo, null, 'CompanySettings');
} catch (Exception $e) {
    error_log("[$requestId] Audit Logger initialization failed: " . $e->getMessage());
    $auditLogger = null;
}

// Initialize JWT Manager
$jwtManager = null;
try {
    $jwtSecretKey = getenv('JWT_SECRET_KEY');
    if (!empty($jwtSecretKey) && strlen($jwtSecretKey) >= 32) {
        $jwtManager = new JWTManager($pdo);
    }
} catch (Exception $e) {
    error_log("[$requestId] JWT Manager initialization failed: " . $e->getMessage());
}

// ============================================
// HELPER FUNCTIONS
// ============================================

/**
 * Send JSON response with proper formatting
 */
function sendResponse($data, $statusCode = 200) {
    http_response_code($statusCode);
    echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
    exit();
}

/**
 * Validate authentication for the request
 */
function validateSettingsRequest($requestId) {
    global $jwtManager, $auditLogger, $pdo;
    
    // Check authentication via multiple methods
    $authenticated = false;
    $memberId = null;
    $authType = 'unknown';
    
    // Method 1: Session authentication
    if (!empty($_SESSION['member_id']) && 
        !empty($_SESSION['authenticated']) && 
        $_SESSION['authenticated'] === true) {
        
        $memberId = $_SESSION['member_id'];
        $authenticated = true;
        $authType = 'session';
        
        // Update last activity
        $_SESSION['last_activity'] = time();
        
        error_log("[$requestId] Session authentication successful for member: $memberId");
    }
    
    // Method 2: JWT authentication
    if (!$authenticated && $jwtManager) {
        $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
        if (preg_match('/Bearer\s+(.*)/i', $authHeader, $matches)) {
            $token = $matches[1];
            
            try {
                $decoded = $jwtManager->validateAccessToken($token);
                if ($decoded && isset($decoded['mid'])) {
                    $memberId = $decoded['mid'];
                    $authenticated = true;
                    $authType = 'jwt';
                    
                    error_log("[$requestId] JWT authentication successful for member: $memberId");
                }
            } catch (Exception $e) {
                error_log("[$requestId] JWT validation failed: " . $e->getMessage());
            }
        }
    }
    
    if (!$authenticated) {
        if ($auditLogger) {
            $auditLogger->log(0, 'settings_unauthorized', [
                'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
                'auth_type' => $authType,
                'request_id' => $requestId,
                'session_id' => session_id()
            ]);
        }
        
        return [false, null, 'unauthorized'];
    }
    
    // Verify member exists (optional - settings might be public)
    try {
        $stmt = $pdo->prepare("
            SELECT id FROM members WHERE id = ?
        ");
        $stmt->execute([$memberId]);
        if (!$stmt->fetch()) {
            error_log("[$requestId] Member not found: $memberId");
            return [false, null, 'member_not_found'];
        }
    } catch (Exception $e) {
        error_log("[$requestId] Member verification failed: " . $e->getMessage());
        // Continue anyway - settings might be accessible
    }
    
    // Log successful authentication
    if ($auditLogger) {
        $auditLogger->log($memberId, 'settings_authenticated', [
            'auth_type' => $authType,
            'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
            'request_id' => $requestId,
            'session_id' => session_id()
        ]);
    }
    
    return [true, $memberId, $authType];
}

/**
 * Get company settings from database
 */
function getCompanySettings($requestId) {
    global $pdo;

    try {
        error_log("[$requestId] Fetching company settings from database");

        $stmt = $pdo->query("
            SELECT 
                id,
                company_name,
                address,
                phone_number,
                email,
                website,
                country,
                city,
                company_logo,
                primary_color,
                secondary_color,
                accent_color,
                member_portal_url,
                support_url,
                user_login_url,
                cs_number,
                currency,
                timezone,
                favicon,
                DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at,
                DATE_FORMAT(updated_at, '%Y-%m-%d %H:%i:%s') as updated_at
            FROM company_settings
            WHERE id = 1
            LIMIT 1
        ");

        $settings = $stmt->fetch(PDO::FETCH_ASSOC);

        // Debug: no data found
        if (!$settings) {
            error_log("[$requestId] No company settings found, using defaults");
            return getDefaultCompanySettings();
        }

        error_log("[$requestId] Company settings fetched successfully");
        return $settings;

    } catch (Exception $e) {
        error_log("[$requestId] Error fetching company settings: " . $e->getMessage());

        // Safe fallback data
        return getDefaultCompanySettings();
    }
}

/**
 * Get default company settings
 */
function getDefaultCompanySettings() {
    return [
        'id' => 1,
        'company_name' => 'Creative SACCO',
        'address' => 'Nairobi, Kenya',
        'phone_number' => '+254 700 000 000',
        'email' => 'info@creativesacco.com',
        'website' => 'www.creativesacco.com',
        'country' => 'Kenya',
        'city' => 'Nairobi',
        'company_logo' => null,
        'primary_color' => '#1E88E5',
        'secondary_color' => '#FFC107',
        'accent_color' => '#E53935',
        'member_portal_url' => '',
        'support_url' => '',
        'user_login_url' => '',
        'cs_number' => '',
        'currency' => 'KES',
        'timezone' => 'Africa/Nairobi',
        'favicon' => null,
        'created_at' => null,
        'updated_at' => null
    ];
}

/**
 * Enhance settings with processed data for frontend
 */
function enhanceSettingsData($settings, $requestId) {
    // Generate full URL for logo if exists
    if (!empty($settings['company_logo'])) {
        $settings['company_logo_url'] = getFullUrl($settings['company_logo']);
    } else {
        $settings['company_logo_url'] = null;
    }
    
    // Generate full URL for favicon if exists
    if (!empty($settings['favicon'])) {
        $settings['favicon_url'] = getFullUrl($settings['favicon']);
    } else {
        $settings['favicon_url'] = null;
    }
    
    // Format phone number for display
    if (!empty($settings['phone_number'])) {
        $settings['phone_formatted'] = formatPhoneNumber($settings['phone_number']);
    }
    
    // Add currency symbol
    $settings['currency_symbol'] = getCurrencySymbol($settings['currency'] ?? 'KES');
    
    // Add branding colors
    $settings['branding'] = [
        'primary' => $settings['primary_color'] ?? '#1E88E5',
        'secondary' => $settings['secondary_color'] ?? '#FFC107',
        'accent' => $settings['accent_color'] ?? '#E53935'
    ];
    
    // Add portal URLs
    $settings['urls'] = [
        'portal' => $settings['member_portal_url'] ?? getBaseUrl(),
        'support' => $settings['support_url'] ?? '',
        'login' => $settings['user_login_url'] ?? ''
    ];
    
    return $settings;
}

/**
 * Get full URL for a relative path
 */
function getFullUrl($path) {
    if (empty($path)) {
        return null;
    }
    
    // If already absolute URL, return as is
    if (filter_var($path, FILTER_VALIDATE_URL)) {
        return $path;
    }
    
    // Clean the path
    $path = ltrim($path, './');
    
    // Build base URL
    $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://';
    $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
    
    // Get base path
    $scriptPath = dirname($_SERVER['SCRIPT_NAME']);
    $basePath = rtrim($scriptPath, '/');
    
    return $protocol . $host . $basePath . '/' . $path;
}

/**
 * Get base URL of the application
 */
function getBaseUrl() {
    $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://';
    $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
    $basePath = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
    
    return $protocol . $host . $basePath;
}

/**
 * Format phone number for display
 */
function formatPhoneNumber($phone) {
    $phone = preg_replace('/[^0-9]/', '', $phone);
    
    if (strlen($phone) === 12 && substr($phone, 0, 3) === '254') {
        // Kenyan format: +254 XXX XXX XXX
        return '+254 ' . substr($phone, 3, 3) . ' ' . substr($phone, 6, 3) . ' ' . substr($phone, 9);
    } elseif (strlen($phone) === 10 && substr($phone, 0, 1) === '0') {
        // Local format: 0XXX XXX XXX
        return substr($phone, 0, 3) . ' ' . substr($phone, 3, 3) . ' ' . substr($phone, 6);
    }
    
    return $phone;
}

/**
 * Get currency symbol
 */
function getCurrencySymbol($currency) {
    $symbols = [
        'KES' => 'KSh',
        'USD' => '$',
        'EUR' => '€',
        'GBP' => '£',
        'TZS' => 'TSh',
        'UGX' => 'USh'
    ];
    
    return $symbols[$currency] ?? $currency;
}

/**
 * Check if member has permission (optional)
 */
function checkMemberPermission($pdo, $memberId, $permission) {
    try {
        // Most members can view company settings
        // Add specific checks if needed
        return true;
    } catch (Exception $e) {
        error_log("Permission check failed: " . $e->getMessage());
        return false;
    }
}

// ============================================
// MAIN API ENDPOINT
// ============================================

// Only allow GET requests
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
    error_log("[$requestId] Invalid method: " . $_SERVER['REQUEST_METHOD']);
    
    sendResponse([
        'success' => false,
        'error' => 'Method not allowed',
        'message' => 'Only GET requests are allowed',
        'meta' => [
            'request_id' => $requestId,
            'timestamp' => time(),
            'allowed_methods' => ['GET']
        ]
    ], 405);
}

try {
    error_log("[$requestId] Processing GET request");
    
    // Validate authentication (optional - settings might be public)
    $requireAuth = isset($_GET['require_auth']) ? filter_var($_GET['require_auth'], FILTER_VALIDATE_BOOLEAN) : true;
    
    $authenticated = false;
    $memberId = null;
    $authType = 'none';
    
    if ($requireAuth) {
        list($authenticated, $memberId, $authType) = validateSettingsRequest($requestId);
        
        if (!$authenticated) {
            error_log("[$requestId] Authentication failed: $authType");
            
            sendResponse([
                'success' => false,
                'error' => 'Authentication required',
                'message' => 'You must be logged in to access company settings',
                'data' => [
                    'auth_required' => true,
                    'auth_type' => $authType,
                    'redirect_to' => 'login.php'
                ],
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time(),
                    'status' => 'unauthorized'
                ]
            ], 401);
        }
        
        error_log("[$requestId] Member authenticated: $memberId, auth type: $authType");
    }
    
    // Rate limiting (prevent abuse)
    if ($requireAuth && $memberId) {
        $rateLimitKey = 'settings_' . $memberId;
        if (!isset($_SESSION[$rateLimitKey])) {
            $_SESSION[$rateLimitKey] = [
                'count' => 0,
                'reset_time' => time() + 60 // 1 minute window
            ];
        }
        
        // Reset counter if window expired
        if (time() > $_SESSION[$rateLimitKey]['reset_time']) {
            $_SESSION[$rateLimitKey] = [
                'count' => 0,
                'reset_time' => time() + 60
            ];
        }
        
        // Check rate limit (max 20 requests per minute)
        if ($_SESSION[$rateLimitKey]['count'] >= 20) {
            error_log("[$requestId] Rate limit exceeded for member $memberId");
            
            sendResponse([
                'success' => false,
                'error' => 'Rate limit exceeded',
                'message' => 'Too many requests. Please wait a moment.',
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time(),
                    'retry_after' => $_SESSION[$rateLimitKey]['reset_time'] - time()
                ]
            ], 429);
        }
        
        // Increment counter
        $_SESSION[$rateLimitKey]['count']++;
    }
    
    // Check database connection
    if (!isset($pdo) || !$pdo instanceof PDO) {
        error_log("[$requestId] Database connection not available");
        
        sendResponse([
            'success' => false,
            'error' => 'Service unavailable',
            'message' => 'Database connection error',
            'meta' => [
                'request_id' => $requestId,
                'timestamp' => time()
            ]
        ], 503);
    }
    
    // Check if member has permission (if authenticated)
    if ($requireAuth && $memberId) {
        $hasPermission = checkMemberPermission($pdo, $memberId, 'view_company_settings');
        if (!$hasPermission) {
            error_log("[$requestId] Member $memberId lacks permission to view company settings");
            
            if ($auditLogger) {
                $auditLogger->log($memberId, 'settings_permission_denied', [
                    'action' => 'fetch_company_settings',
                    'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
                    'request_id' => $requestId
                ]);
            }
            
            sendResponse([
                'success' => false,
                'error' => 'Access denied',
                'message' => 'You do not have permission to view company settings',
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time()
                ]
            ], 403);
        }
    }
    
    // Get company settings
    $settings = getCompanySettings($requestId);
    
    // Enhance settings with processed data
    $enhancedSettings = enhanceSettingsData($settings, $requestId);
    
    // Add request context
    $enhancedSettings['_context'] = [
        'member_id' => $memberId,
        'auth_type' => $authType,
        'session_id' => session_id(),
        'request_id' => $requestId,
        'timestamp' => time()
    ];
    
    // Log successful fetch
    if ($auditLogger && $memberId) {
        $auditLogger->log($memberId, 'settings_fetched', [
            'settings_id' => $settings['id'],
            'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
            'request_id' => $requestId
        ]);
    }
    
    error_log("[$requestId] Settings fetched successfully");
    
    // Update last activity if authenticated
    if ($requireAuth && isset($_SESSION['last_activity'])) {
        $_SESSION['last_activity'] = time();
    }
    
    // Calculate response time
    $responseTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
    
    // Return success response
    sendResponse([
        'success' => true,
        'message' => 'Company settings retrieved successfully',
        'data' => $enhancedSettings,
        'meta' => [
            'request_id' => $requestId,
            'timestamp' => time(),
            'api_version' => '1.0',
            'endpoint' => 'company_settings',
            'response_time' => round($responseTime, 3),
            'authenticated' => $requireAuth && $authenticated,
            'member_id' => $memberId,
            'memory_usage' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB',
            'server' => gethostname()
        ]
    ]);
    
} catch (Exception $e) {
    error_log("[$requestId] ERROR: " . $e->getMessage());
    error_log("[$requestId] Stack trace: " . $e->getTraceAsString());
    
    sendResponse([
        'success' => false,
        'error' => 'Internal server error',
        'message' => 'Failed to fetch company settings',
        'meta' => [
            'request_id' => $requestId,
            'timestamp' => time(),
            'support_contact' => 'support@creativesacco.com'
        ]
    ], 500);
}

error_log("[$requestId] === FETCH COMPANY SETTINGS REQUEST END ===");
error_log("[$requestId] Total execution time: " . round(microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'], 3) . " seconds");
?>