/**
 * Improved Cookie Interceptor
 *
 * Handles multiple Filevine sessions robustly by being tab-aware.
 * When a user has multiple Filevine accounts open in different tabs,
 * this interceptor ensures we use the cookies from the ACTIVE tab.
 */

import { MESSAGE_TYPES, API_BASE_URL, ENDPOINTS } from '../lib/constants.js';
import { authManager } from './auth.js';
import { webApiClient } from './web-api-client.js';

let lastCookieValue = null;
let activeTabId = null;
let tabOrgMap = new Map(); // Map of tabId -> orgId
let tabSessionMap = new Map(); // Map of tabId -> { orgId, orgName, userEmail, url, lastActive }

/**
 * Setup improved cookie interception with tab awareness
 */
export function setupCookieInterceptor() {
  console.log('[Cookie Interceptor] Setting up tab-aware cookie interception...');

  // Track active tab changes
  chrome.tabs.onActivated.addListener(async (activeInfo) => {
    activeTabId = activeInfo.tabId;
    console.log('[Cookie Interceptor] Active tab changed to:', activeTabId);

    // Check if this is a Filevine tab
    const tab = await chrome.tabs.get(activeTabId);
    if (tab.url?.includes('filevineapp.com')) {
      console.log('[Cookie Interceptor] Active Filevine tab detected, refreshing auth...');
      // Give the page a moment to load
      setTimeout(() => checkCookiesForActiveTab(), 1000);
    }
  });

  // Track tab updates (URL changes, page loads)
  chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    if (changeInfo.status === 'complete' && tab.url?.includes('filevineapp.com')) {
      console.log('[Cookie Interceptor] Filevine tab loaded:', tabId);
      if (tabId === activeTabId) {
        console.log('[Cookie Interceptor] Active Filevine tab updated, refreshing auth...');
        setTimeout(() => checkCookiesForActiveTab(), 1000);
      }
    }
  });

  // Listen for cookie changes
  chrome.cookies.onChanged.addListener((changeInfo) => {
    if (changeInfo.cookie.domain.includes('filevineapp.com')) {
      console.log('[Cookie Interceptor] Cookie changed:', changeInfo.cookie.name);
      if (changeInfo.cookie.name.includes('ApplicationCookie')) {
        // Cookie changed, check if it's for the active tab
        checkCookiesForActiveTab();
      }
    }
  });

  // Initial check for cookies
  checkCookiesForActiveTab();

  // Periodic refresh (but be smart about it)
  setInterval(() => {
    // Only refresh if user might have switched accounts
    checkCookiesForActiveTab();
  }, 10000); // Every 10 seconds
}

/**
 * Check cookies specifically for the active Filevine tab
 * This prevents confusion when multiple accounts are logged in
 */
async function checkCookiesForActiveTab() {
  try {
    // Get active tab
    const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });

    if (!activeTab) {
      console.log('[Cookie Interceptor] No active tab found');
      return;
    }

    // Only proceed if active tab is a Filevine page
    if (!activeTab.url || !activeTab.url.includes('filevineapp.com')) {
      console.log('[Cookie Interceptor] Active tab is not a Filevine page:', activeTab.url);
      return;
    }

    console.log('[Cookie Interceptor] Checking cookies for active Filevine tab:', activeTab.id);
    console.log('[Cookie Interceptor] Active tab URL:', activeTab.url);

    // Parse the URL to get subdomain/org info
    const url = new URL(activeTab.url);
    const subdomain = url.hostname.split('.')[0]; // e.g., "app" or "orgname"

    console.log('[Cookie Interceptor] Active tab subdomain:', subdomain);

    // Get all cookies for Filevine
    const cookies = await chrome.cookies.getAll({
      domain: 'filevineapp.com'
    });

    console.log('[Cookie Interceptor] Found', cookies.length, 'cookies for filevineapp.com');

    // Find ASP.NET Application Cookie
    const appCookie = cookies.find(c => c.name === '.AspNet.ApplicationCookie');
    const cookieC1 = cookies.find(c => c.name === '.AspNet.ApplicationCookieC1');
    const cookieC2 = cookies.find(c => c.name === '.AspNet.ApplicationCookieC2');

    if (!appCookie) {
      console.log('[Cookie Interceptor] No ASP.NET cookie found. User may not be logged in.');
      console.log('[Cookie Interceptor] Available cookies:', cookies.map(c => c.name).join(', '));
      return;
    }

    // Build full cookie string (ASP.NET uses chunked cookies)
    let cookieHeader = `.AspNet.ApplicationCookie=${appCookie.value}`;
    if (cookieC1) cookieHeader += `; .AspNet.ApplicationCookieC1=${cookieC1.value}`;
    if (cookieC2) cookieHeader += `; .AspNet.ApplicationCookieC2=${cookieC2.value}`;

    // Only process if cookie changed OR if this is a different tab
    const cookieChanged = appCookie.value !== lastCookieValue;
    const tabChanged = activeTab.id !== activeTabId;

    if (cookieChanged || tabChanged) {
      lastCookieValue = appCookie.value;
      activeTabId = activeTab.id;

      console.log('[Cookie Interceptor] ✅ Processing auth for active tab');
      console.log('[Cookie Interceptor] Cookie preview:', appCookie.value.substring(0, 50) + '...');
      console.log('[Cookie Interceptor] Cookie domain:', appCookie.domain);

      // Try to get org info for the active tab
      await processAuthForActiveTab(cookieHeader, activeTab);
    } else {
      console.log('[Cookie Interceptor] Cookie unchanged and same tab, skipping');
    }

  } catch (error) {
    console.error('[Cookie Interceptor] Error checking cookies:', error);
  }
}

/**
 * Process authentication for the active tab
 * Gets org info from the web API and ensures it matches the active tab
 */
async function processAuthForActiveTab(cookieHeader, activeTab) {
  try {
    console.log('[Cookie Interceptor] Fetching org info from web API...');

    // Call web app API to get list of orgs this user has access to
    const response = await fetch('https://product.filevineapp.com/api/orgs', {
      method: 'GET',
      headers: {
        'Cookie': cookieHeader,
        'Content-Type': 'application/json'
      },
      credentials: 'include'
    });

    if (!response.ok) {
      const errorText = await response.text();
      console.error('[Cookie Interceptor] Failed to fetch orgs:', response.status, errorText.substring(0, 200));
      return;
    }

    const data = await response.json();

    if (!data.success || !data.data || data.data.length === 0) {
      console.error('[Cookie Interceptor] No orgs found in response:', data);
      return;
    }

    const orgs = data.data;
    console.log('[Cookie Interceptor] User has access to', orgs.length, 'org(s)');

    // If user has multiple orgs, try to determine which one they're viewing
    let selectedOrg = orgs[0]; // Default to first

    if (orgs.length > 1) {
      console.log('[Cookie Interceptor] Multiple orgs detected, attempting to match with active tab...');

      // Try to determine org from URL
      // Option 1: Extract from URL path (e.g., /org/12345/projects)
      const orgIdMatch = activeTab.url.match(/\/org\/(\d+)/);
      if (orgIdMatch) {
        const urlOrgId = orgIdMatch[1];
        console.log('[Cookie Interceptor] Found org ID in URL:', urlOrgId);

        const matchingOrg = orgs.find(o => String(o.id) === urlOrgId);
        if (matchingOrg) {
          selectedOrg = matchingOrg;
          console.log('[Cookie Interceptor] ✅ Matched org from URL:', selectedOrg.name);
        }
      }

      // Option 2: Send message to content script to ask what org is currently displayed
      try {
        const orgFromPage = await chrome.tabs.sendMessage(activeTab.id, {
          type: 'GET_CURRENT_ORG'
        });

        if (orgFromPage?.orgId) {
          console.log('[Cookie Interceptor] Content script reported org ID:', orgFromPage.orgId);
          const matchingOrg = orgs.find(o => String(o.id) === String(orgFromPage.orgId));
          if (matchingOrg) {
            selectedOrg = matchingOrg;
            console.log('[Cookie Interceptor] ✅ Matched org from content script:', selectedOrg.name);
          }
        }
      } catch (e) {
        console.log('[Cookie Interceptor] Could not get org from content script:', e.message);
      }

      // Option 3: Check if we have a stored preference for this tab
      if (tabOrgMap.has(activeTab.id)) {
        const preferredOrgId = tabOrgMap.get(activeTab.id);
        const matchingOrg = orgs.find(o => String(o.id) === String(preferredOrgId));
        if (matchingOrg) {
          selectedOrg = matchingOrg;
          console.log('[Cookie Interceptor] ✅ Using stored org preference for this tab:', selectedOrg.name);
        }
      }

      console.log('[Cookie Interceptor] Selected org:', selectedOrg.name, '(ID:', selectedOrg.id, ')');

      // If we still have multiple orgs and couldn't determine which, warn user
      if (!orgIdMatch && orgs.length > 1) {
        console.warn('[Cookie Interceptor] ⚠️  User has', orgs.length, 'orgs but could not determine which is active');
        console.warn('[Cookie Interceptor] Using:', selectedOrg.name);
        console.warn('[Cookie Interceptor] If this is wrong, user should switch to the correct org tab');
      }
    } else {
      console.log('[Cookie Interceptor] Single org, using:', selectedOrg.name);
    }

    // Store this mapping
    tabOrgMap.set(activeTab.id, selectedOrg.id);

    // Store session info for multi-session tracking
    updateTabSession(activeTab.id, {
      orgId: String(selectedOrg.id),
      orgName: selectedOrg.name,
      userEmail: `User ${selectedOrg.ownerID || selectedOrg.ownerId}`, // /api/orgs doesn't include email
      url: activeTab.url,
      availableOrgs: orgs.map(o => ({ id: o.id, name: o.name }))
    });

    // Store in session for reference
    chrome.storage.session.set({
      'fv_cookie': cookieHeader,
      'fv_org_id': String(selectedOrg.id),
      'fv_org_name': selectedOrg.name,
      'fv_user_id': String(selectedOrg.ownerID || selectedOrg.ownerId),
      'fv_using_web_api': true,
      'fv_active_tab_id': activeTab.id,
      'fv_cookie_timestamp': Date.now(),
      'fv_available_orgs': orgs.map(o => ({ id: o.id, name: o.name }))
    });

    // Process auth through auth manager
    console.log('[Cookie Interceptor] Processing auth with org:', selectedOrg.name);

    const auth = await authManager.processCookieAuth({
      orgId: String(selectedOrg.id),
      orgName: selectedOrg.name,
      userId: String(selectedOrg.ownerID || selectedOrg.ownerId),
      cookie: cookieHeader
    });

    // Initialize web API client
    if (auth && auth.usingWebApi) {
      webApiClient.setCredentials({
        cookie: cookieHeader,
        userId: String(selectedOrg.ownerID || selectedOrg.ownerId),
        orgId: String(selectedOrg.id)
      });
      console.log('[Cookie Interceptor] ✅ Auth complete for', selectedOrg.name);
    }

  } catch (error) {
    console.error('[Cookie Interceptor] Error processing auth:', error);
  }
}

/**
 * Allow user to manually switch org (for multi-org users)
 */
export async function switchToOrg(orgId) {
  const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });
  if (activeTab) {
    tabOrgMap.set(activeTab.id, orgId);
    // Re-process auth with new org
    await checkCookiesForActiveTab();
  }
}

/**
 * Clear tab mapping when tab is closed
 */
chrome.tabs.onRemoved.addListener((tabId) => {
  if (tabOrgMap.has(tabId)) {
    console.log('[Cookie Interceptor] Removing org mapping for closed tab:', tabId);
    tabOrgMap.delete(tabId);
  }
  if (tabSessionMap.has(tabId)) {
    console.log('[Cookie Interceptor] Removing session mapping for closed tab:', tabId);
    tabSessionMap.delete(tabId);
  }
});

/**
 * Get all active Filevine sessions across all tabs
 * Returns an array of session objects with tab info
 */
export async function getAllActiveSessions() {
  try {
    // Get all tabs with Filevine URLs
    const filevineTabs = await chrome.tabs.query({
      url: ['https://*.filevineapp.com/*']
    });

    console.log('[Cookie Interceptor] Found', filevineTabs.length, 'Filevine tabs');

    const sessions = [];

    for (const tab of filevineTabs) {
      try {
        // Extract org from URL if possible
        const url = new URL(tab.url);
        const subdomain = url.hostname.split('.')[0];

        // Get cookies for this specific tab's domain
        const cookies = await chrome.cookies.getAll({
          domain: 'filevineapp.com'
        });

        const applicationCookie = cookies.find(c => c.name.includes('ApplicationCookie'));

        if (!applicationCookie) {
          console.log('[Cookie Interceptor] Tab', tab.id, 'has no valid auth cookie');
          continue;
        }

        // Try to get cached session info first
        let sessionInfo = tabSessionMap.get(tab.id);

        if (!sessionInfo) {
          // If not cached, try to extract from current auth state
          const authState = authManager.getState();
          if (authState.authenticated && authState.auth) {
            sessionInfo = {
              orgId: authState.auth.orgId,
              orgName: authState.auth.orgName || `Org ${authState.auth.orgId}`,
              userEmail: authState.auth.userEmail || authState.auth.userId || 'User',
              url: tab.url,
              lastActive: Date.now()
            };
            // Cache it
            tabSessionMap.set(tab.id, sessionInfo);
          } else {
            // Fallback to minimal info
            sessionInfo = {
              orgId: subdomain,
              orgName: subdomain,
              userEmail: 'Unknown',
              url: tab.url,
              lastActive: Date.now()
            };
          }
        }

        sessions.push({
          tabId: tab.id,
          tabTitle: tab.title,
          isActive: tab.active,
          ...sessionInfo
        });

      } catch (error) {
        console.error('[Cookie Interceptor] Error processing tab', tab.id, error);
      }
    }

    // Sort by active status (active first) then by last active time
    sessions.sort((a, b) => {
      if (a.isActive && !b.isActive) return -1;
      if (!a.isActive && b.isActive) return 1;
      return (b.lastActive || 0) - (a.lastActive || 0);
    });

    console.log('[Cookie Interceptor] Returning', sessions.length, 'active sessions');
    return sessions;

  } catch (error) {
    console.error('[Cookie Interceptor] Error getting active sessions:', error);
    return [];
  }
}

/**
 * Update session info for a tab (called when auth is detected)
 */
export function updateTabSession(tabId, sessionInfo) {
  console.log('[Cookie Interceptor] Updating session for tab', tabId, sessionInfo);
  tabSessionMap.set(tabId, {
    ...sessionInfo,
    lastActive: Date.now()
  });
}
