// Identity Manager - Background Module
// Caches user identity (domain-only) per site, evaluates identity policies

const PERSONAL_DOMAINS = [
  'gmail.com', 'yahoo.com', 'outlook.com', 'hotmail.com', 'aol.com',
  'icloud.com', 'protonmail.com', 'live.com', 'msn.com', 'yandex.com',
  'mail.com', 'zoho.com'
];

export class IdentityManager {
  constructor(config = {}) {
    this.apiUrl = config.apiUrl || 'https://api.portal.nithic.ai';
    this.enabled = config.enabled !== false;
    this.apiKey = config.apiKey || null;

    // Identity cache: siteDomain → { identityDomain, identityType, capturedAt, method }
    this.identities = new Map();

    // Identity policies fetched from dashboard API
    this.policies = [];
    this.orgConfig = null;

    // Restore from session storage + fetch policies
    this._restore();
    this._fetchPolicies();
    this._fetchOrgConfig();

    // Refresh policies every 5 minutes
    this._policyTimer = setInterval(() => {
      this._fetchPolicies();
      this._fetchOrgConfig();
    }, 5 * 60 * 1000);

    console.log('✓ Identity Manager initialized');
  }

  /**
   * Store a detected identity for a site domain
   */
  setIdentity(siteDomain, identityDomain, method = 'form_login') {
    const identityType = this.classifyDomain(identityDomain);
    const entry = {
      identityDomain,
      identityType,
      capturedAt: Date.now(),
      method
    };

    this.identities.set(siteDomain, entry);
    this._persist();

    console.log(`Identity detected: ${siteDomain} → @${identityDomain} (${identityType}) via ${method}`);
    return entry;
  }

  /**
   * Get the current identity for a site domain
   */
  getIdentity(siteDomain) {
    return this.identities.get(siteDomain) || null;
  }

  /**
   * Get identity for a tab's current site (by tab URL hostname)
   */
  getIdentityForHost(hostname) {
    // Direct match
    if (this.identities.has(hostname)) return this.identities.get(hostname);

    // Try without www
    const noWww = hostname.replace(/^www\./, '');
    if (this.identities.has(noWww)) return this.identities.get(noWww);

    // Try parent domain
    const parts = hostname.split('.');
    if (parts.length > 2) {
      const parent = parts.slice(1).join('.');
      if (this.identities.has(parent)) return this.identities.get(parent);
    }

    return null;
  }

  /**
   * Classify a domain as personal or enterprise
   */
  classifyDomain(domain) {
    if (!domain) return 'unknown';
    const lower = domain.toLowerCase();

    if (PERSONAL_DOMAINS.includes(lower)) return 'personal';

    // Check if it's a known enterprise domain from org config
    if (this.orgConfig && this.orgConfig.allowed_enterprise_domains) {
      if (this.orgConfig.allowed_enterprise_domains.includes(lower)) return 'enterprise';
    }

    // If it's not personal and not in enterprise whitelist, still classify as enterprise
    // (most custom domains are corporate)
    if (!PERSONAL_DOMAINS.includes(lower)) return 'enterprise';

    return 'unknown';
  }

  /**
   * Check if an action is allowed given current identity on an AI service
   * Returns { allowed: true } or { allowed: false, policyName, reason }
   */
  evaluatePolicy(aiService, action, siteDomain) {
    // If no identity detected, allow (can't enforce)
    const identity = this.getIdentityForHost(siteDomain);
    if (!identity) return { allowed: true };

    // Check org-level config first
    if (this.orgConfig && this.orgConfig.personal_domains_blocked && identity.identityType === 'personal') {
      const blockedActions = this.orgConfig.personal_domains_block_actions || [];
      if (blockedActions.includes(action)) {
        return {
          allowed: false,
          policyName: 'Org: Personal Account Blocked',
          reason: `Personal accounts (@${identity.identityDomain}) are not allowed to ${action} on AI services`
        };
      }
    }

    // Check enterprise-only services
    if (this.orgConfig && this.orgConfig.enterprise_only_services) {
      if (this.orgConfig.enterprise_only_services.includes(aiService) && identity.identityType === 'personal') {
        return {
          allowed: false,
          policyName: 'Org: Enterprise Only Service',
          reason: `${aiService} is restricted to enterprise accounts only`
        };
      }
    }

    // Check individual identity policies
    for (const policy of this.policies) {
      if (!policy.is_active) continue;

      // Policy must match identity type
      if (policy.identity_type !== identity.identityType) continue;

      // If policy specifies domains, identity must match one
      if (policy.identity_domains && policy.identity_domains.length > 0) {
        if (!policy.identity_domains.includes(identity.identityDomain)) continue;
      }

      // Check if action is blocked
      if (policy.blocked_actions && policy.blocked_actions.includes(action)) {
        // Check if AI service is targeted (empty = all services)
        if (policy.blocked_ai_services && policy.blocked_ai_services.length > 0) {
          if (!policy.blocked_ai_services.includes(aiService)) continue;
        }

        return {
          allowed: false,
          policyName: policy.name,
          reason: `Policy "${policy.name}": ${action} blocked for ${identity.identityType} accounts on ${aiService}`
        };
      }
    }

    return { allowed: true };
  }

  /**
   * Extract domain from email address (discard username for privacy)
   */
  static extractDomain(emailOrUsername) {
    if (!emailOrUsername) return null;
    const atIndex = emailOrUsername.indexOf('@');
    if (atIndex === -1) return null;
    return emailOrUsername.substring(atIndex + 1).toLowerCase().trim();
  }

  /**
   * Persist identities to chrome.storage.session
   */
  _persist() {
    try {
      const data = {};
      for (const [key, val] of this.identities) {
        data[key] = val;
      }
      chrome.storage.session.set({ identityCache: data });
    } catch (e) {
      // Session storage may not be available
    }
  }

  /**
   * Restore identities from chrome.storage.session
   */
  async _restore() {
    try {
      const result = await chrome.storage.session.get('identityCache');
      if (result.identityCache) {
        for (const [key, val] of Object.entries(result.identityCache)) {
          this.identities.set(key, val);
        }
        console.log(`Identity Manager: Restored ${this.identities.size} cached identities`);
      }
    } catch (e) {
      // Session storage may not be available
    }
  }

  /**
   * Fetch identity policies from dashboard API
   */
  async _fetchPolicies() {
    try {
      const headers = {};
      if (this.apiKey) headers['X-API-Key'] = this.apiKey;
      const response = await fetch(`${this.apiUrl}/api/ai-visibility/identity-policies`, { headers });
      if (response.ok) {
        const data = await response.json();
        this.policies = data.policies || [];
        console.log(`Identity Manager: Loaded ${this.policies.length} identity policies`);
      }
    } catch (e) {
      console.warn('Identity Manager: Could not fetch policies:', e.message);
    }
  }

  /**
   * Fetch org identity config from dashboard API
   */
  async _fetchOrgConfig() {
    try {
      const headers = {};
      if (this.apiKey) headers['X-API-Key'] = this.apiKey;
      const response = await fetch(`${this.apiUrl}/api/ai-visibility/identity-config`, { headers });
      if (response.ok) {
        const data = await response.json();
        this.orgConfig = data.config || null;
        console.log('Identity Manager: Loaded org config');
      }
    } catch (e) {
      console.warn('Identity Manager: Could not fetch org config:', e.message);
    }
  }

  destroy() {
    if (this._policyTimer) clearInterval(this._policyTimer);
  }
}
