<?php

/**
 * Multi-Tenant Manager - Handles company scoping and workspace management
 */
class TenantManager {
    private static $currentCompanyId = null;
    private static $tenantData = null;
    
    /**
     * Initialize tenant context from subdomain or session
     */
    public static function initialize(): void {
        // For local development, skip subdomain logic and use session/user company
        $host = $_SERVER['HTTP_HOST'] ?? '';
        
        if (strpos($host, 'localhost') !== false) {
            // Local development - use authenticated user's company
            $company = AuthManager::getCurrentCompany();
            if ($company) {
                self::$currentCompanyId = $company['id'];
                self::$tenantData = $company;
            }
            return;
        }
        
        // Production - try subdomain logic
        $subdomain = self::extractSubdomain();
        
        if ($subdomain) {
            self::setCurrentCompanyBySubdomain($subdomain);
        } else {
            // Fallback to authenticated user's company
            $company = AuthManager::getCurrentCompany();
            if ($company) {
                self::$currentCompanyId = $company['id'];
                self::$tenantData = $company;
            }
        }
    }
    
    /**
     * Set current company manually
     */
    public static function setCurrentCompany(int $companyId, array $companyData): void {
        self::$currentCompanyId = $companyId;
        self::$tenantData = $companyData;
    }
    
    /**
     * Get current company ID
     */
    public static function getCurrentCompanyId(): ?int {
        if (self::$currentCompanyId === null) {
            self::initialize();
        }
        
        return self::$currentCompanyId;
    }
    
    /**
     * Get current company data
     */
    public static function getCurrentCompany(): ?array {
        // Always check session first (most up-to-date)
        if (isset($_SESSION['current_company'])) {
            self::$currentCompanyId = $_SESSION['current_company']['id'];
            self::$tenantData = $_SESSION['current_company'];
            return self::$tenantData;
        }
        
        // If no session data, try to initialize
        if (self::$currentCompanyId === null) {
            self::initialize();
        }
        
        return self::$tenantData;
    }
    
    /**
     * Set current company by subdomain
     */
    public static function setCurrentCompanyBySubdomain(string $subdomain): bool {
        $pdo = getPDO();
        
        $stmt = $pdo->prepare("
            SELECT c.*, sp.name as plan_name, sp.limits
            FROM companies c
            LEFT JOIN subscription_plans sp ON c.plan_id = sp.id
            WHERE c.subdomain = ?
        ");
        
        $stmt->execute([$subdomain]);
        $company = $stmt->fetch();
        
        if ($company) {
            self::$currentCompanyId = $company['id'];
            self::$tenantData = $company;
            
            // Check subscription status
            if ($company['subscription_status'] === 'trial' && strtotime($company['subscription_expires_at']) < time()) {
                // Trial expired
                self::redirectToBilling();
            } elseif ($company['subscription_status'] === 'past_due') {
                // Payment overdue
                self::redirectToBilling();
            }
            
            return true;
        }
        
        return false;
    }
    
    /**
     * Scope query to current company
     */
    public static function scopeQuery(string $query, array $params = []): array {
        $companyId = self::getCurrentCompanyId();
        
        if ($companyId === null) {
            throw new Exception('No company context available');
        }
        
        // Add company_id condition to WHERE clause
        if (stripos($query, 'WHERE') !== false) {
            $query = preg_replace('/WHERE\s+/i', 'WHERE (', $query, 1);
            $query .= ') AND company_id = ?';
        } else {
            $query .= ' WHERE company_id = ?';
        }
        
        $params[] = $companyId;
        
        return [$query, $params];
    }
    
    /**
     * Get user's accessible companies
     */
    public static function getUserCompanies(int $userId): array {
        $pdo = getPDO();
        
        $stmt = $pdo->prepare("
            SELECT c.*, u.role, sp.name as plan_name
            FROM companies c
            JOIN users u ON u.company_id = c.id
            LEFT JOIN subscription_plans sp ON c.plan_id = sp.id
            WHERE u.id = ? AND u.is_active = 1
            ORDER BY u.role DESC, c.name
        ");
        
        $stmt->execute([$userId]);
        return $stmt->fetchAll();
    }
    
    /**
     * Switch to different company/workspace
     */
    public static function switchCompany(int $companyId): bool {
        try {
            $pdo = getPDO();
            
            // For now, allow switching to any company (simplified for demo)
            // In production, you should check user permissions
            
            // Verify company exists
            $stmt = $pdo->prepare("SELECT * FROM companies WHERE id = ?");
            $stmt->execute([$companyId]);
            $company = $stmt->fetch();
            
            if (!$company) {
                return false;
            }
            
            // Update session with complete company data
            $_SESSION['current_company_id'] = $companyId;
            $_SESSION['current_company'] = $company;
            
            // Update static properties
            self::$currentCompanyId = $companyId;
            self::$tenantData = $company;
            
            // Debug log
            error_log("TenantManager::switchCompany - Updated session with company ID: " . $companyId . ", Name: " . $company['name']);
            
            return true;
            
        } catch (Exception $e) {
            error_log("Error switching company: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Check if current company can perform action based on plan limits
     */
    public static function canPerformAction(string $action, int $count = 1): bool {
        $company = self::getCurrentCompany();
        
        if (!$company) {
            return false;
        }
        
        $limits = json_decode($company['limits'] ?? '{}', true);
        
        if (!isset($limits[$action])) {
            return true; // No limit defined
        }
        
        $limit = $limits[$action];
        
        if ($limit === -1) {
            return true; // Unlimited
        }
        
        // Check current usage
        $currentUsage = self::getCurrentUsage($action);
        
        return ($currentUsage + $count) <= $limit;
    }
    
    /**
     * Get current usage for a specific metric
     */
    public static function getCurrentUsage(string $metric): int {
        $companyId = self::getCurrentCompanyId();
        $pdo = getPDO();
        
        switch ($metric) {
            case 'proposals_per_month':
                $stmt = $pdo->prepare("
                    SELECT COUNT(*) as count 
                    FROM proposals 
                    WHERE company_id = ? AND MONTH(created_at) = MONTH(CURRENT_DATE) 
                    AND YEAR(created_at) = YEAR(CURRENT_DATE)
                ");
                $stmt->execute([$companyId]);
                return $stmt->fetch()['count'];
                
            case 'clients':
                $stmt = $pdo->prepare("SELECT COUNT(*) as count FROM clients WHERE company_id = ?");
                $stmt->execute([$companyId]);
                return $stmt->fetch()['count'];
                
            case 'users':
                $stmt = $pdo->prepare("SELECT COUNT(*) as count FROM users WHERE company_id = ? AND is_active = 1");
                $stmt->execute([$companyId]);
                return $stmt->fetch()['count'];
                
            case 'templates':
                // Templates table doesn't exist in current schema, return 0
                return 0;
                
            default:
                return 0;
        }
    }
    
    /**
     * Track usage for billing and limits
     */
    public static function trackUsage(string $metric, int $value = 1): void {
        $companyId = self::getCurrentCompanyId();
        $pdo = getPDO();
        
        $stmt = $pdo->prepare("
            INSERT INTO usage_tracking (company_id, metric_name, metric_value, period_type, period_date)
            VALUES (?, ?, ?, 'monthly', DATE(CURRENT_DATE))
            ON DUPLICATE KEY UPDATE metric_value = metric_value + ?
        ");
        
        $stmt->execute([$companyId, $metric, $value, $value]);
    }
    
    /**
     * Extract subdomain from current request
     */
    private static function extractSubdomain(): ?string {
        $host = $_SERVER['HTTP_HOST'] ?? '';
        $baseDomain = self::getBaseDomain();
        
        if ($host === $baseDomain) {
            return null;
        }
        
        $subdomain = str_replace('.' . $baseDomain, '', $host);
        
        // Skip www subdomain
        if ($subdomain === 'www') {
            return null;
        }
        
        return $subdomain;
    }
    
    /**
     * Get base domain from current host
     */
    private static function getBaseDomain(): string {
        $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
        
        // For local development
        if (strpos($host, 'localhost') !== false) {
            return 'localhost';
        }
        
        // Extract domain from subdomain.domain.com
        $parts = explode('.', $host);
        
        if (count($parts) >= 2) {
            return implode('.', array_slice($parts, -2));
        }
        
        return $host;
    }
    
    /**
     * Redirect to billing page
     */
    private static function redirectToBilling(): void {
        header('Location: /billing.php');
        exit;
    }
    
    /**
     * Require active subscription
     */
    public static function requireActiveSubscription(): void {
        $company = self::getCurrentCompany();
        
        if (!$company) {
            header('Location: /login.php');
            exit;
        }
        
        if ($company['subscription_status'] === 'trial' && strtotime($company['subscription_expires_at']) < time()) {
            $_SESSION['error'] = 'Your trial has expired. Please upgrade to continue.';
            header('Location: /billing.php');
            exit;
        }
        
        if ($company['subscription_status'] === 'past_due' || $company['subscription_status'] === 'canceled') {
            $_SESSION['error'] = 'Your subscription is not active. Please update your payment method.';
            header('Location: /billing.php');
            exit;
        }
    }
}
