// Universal Auth Module: Immutable, Pattern-Based, Project-Agnostic
// Usage: import and call Auth.use('pb-graph') or Auth.use('pb') or Auth.use('graph')
// Provides: getToken(type), ensureToken(type), refreshToken(type), getUserInfo(), promptReauth()
// Token types: 'pb' (PocketBase user/agent), 'graph' (Graph delegated), 'graphAgent' (Graph app-only)
// All storage, retrieval, refresh, and UI are standardized and immutable

const TOKEN_KEYS = {
  'pb-user': 'pbUserToken',
  'pb-agent': 'pbAgentToken',
  'graph-user': 'graphUserToken',
  'graph-agent': 'graphAgentToken'
};

function parsePattern(pattern) {
  return pattern.split('+').map(s => s.trim()).filter(Boolean);
}

window.Auth = (() => {
  let pattern = 'pb-user'; // default
  let enabledTypes = ['pb-user'];
  let pb = null;
  let popup = null;
  let agentCreds = { email: '', password: '' };
  let superuserCreds = { email: '', password: '' };

  // --- Setup ---
  function use(type) {
    pattern = type;
    enabledTypes = parsePattern(type);
    if (enabledTypes.some(t => t.startsWith('pb'))) {
      pb = window.PocketBase ? new PocketBase('https://pocketbase.ccllc.pro') : null;
    }
    // Only one-time setup
    if (!document.getElementById('authPopup')) {
      createPopup();
    }
  }

  // --- Token Storage ---
  function getToken(type) {
    return localStorage.getItem(TOKEN_KEYS[type]) || '';
  }
  function setToken(type, value) {
    if (value) localStorage.setItem(TOKEN_KEYS[type], value);
  }
  function clearToken(type) {
    localStorage.removeItem(TOKEN_KEYS[type]);
  }

  // --- Info Extraction ---
  function getUserInfo() {
    if (pb && pb.authStore.model) {
      return {
        displayName: pb.authStore.model.display_name || pb.authStore.model.name || pb.authStore.model.email || pb.authStore.model.username || 'Unknown',
        email: pb.authStore.model.email || pb.authStore.model.username || null
      };
    }
    return { displayName: '', email: '' };
  }

  // --- Token Ensure/Refresh ---
  async function ensureToken(type) {
    let token = getToken(type);
    if (token) return token;
    if (type === 'pb-user' && pb) {
      if (pb.authStore.isValid) {
        setToken('pb-user', pb.authStore.token);
        return pb.authStore.token;
      }
      // Choose login method: email/password or OAuth
      if (pattern.includes('pb-user-oauth')) {
        return await promptReauth('pb-user-oauth');
      } else {
        return await promptReauth('pb-user');
      }
    }
    if (type === 'pb-superuser' && pb) {
      // Prompt for superuser credentials
      await promptReauth('pb-superuser');
      // Use superuser credentials to login
      const authData = await pb.collection('_superuser').authWithPassword(superuserCreds.email, superuserCreds.password);
      setToken('pb-superuser', pb.authStore.token);
      return pb.authStore.token;
    }
    if (type === 'pb-agent' && pb) {
      // Prompt for agent credentials if not set
      if (!agentCreds.email || !agentCreds.password) {
        await promptReauth('pb-agent');
      }
      // Use agent credentials to login
      const authData = await pb.collection('users').authWithPassword(agentCreds.email, agentCreds.password);
      setToken('pb-agent', pb.authStore.token);
      return pb.authStore.token;
    }
    if (type === 'graph-user' && pb) {
      // OAuth only
      return await promptReauth('graph-user');
    }
    if (type === 'graph-agent') {
      // Prompt for agent credentials if not set
      if (!agentCreds.email || !agentCreds.password) {
        await promptReauth('graph-agent');
      }
      // Use agent credentials to get token (simulate, real flow is backend)
      setToken('graph-agent', 'AGENT_TOKEN_' + agentCreds.email);
      return getToken('graph-agent');
    }
    throw new Error('Unknown token type');
  }

  async function refreshToken(type) {
    if (type === 'graph-user' && pb) {
      try {
        const authData = await pb.collection('users').authRefresh();
        const meta = authData?.meta || pb?.authStore?.model?.meta || {};
        const token = meta.graphAccessToken || meta.graph_token || meta.graphToken || meta.accessToken || meta.access_token || meta.token || meta.rawToken || meta?.authData?.access_token || '';
        setToken('graph-user', token);
        return token || '';
      } catch (err) {
        return '';
      }
    }
    // Add refresh logic for other types as needed
    return '';
  }

  // --- Reauth Popup ---
  function createPopup() {
    popup = document.createElement('div');
    popup.id = 'authPopup';
    popup.style = 'display:none;position:fixed;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,0.4);z-index:9999;align-items:center;justify-content:center;';
    popup.innerHTML = `
      <div style="background:#fff;padding:2em 2.5em;border-radius:1em;box-shadow:0 2px 24px #0002;text-align:center;max-width:350px;margin:auto;">
        <h2 style="font-size:1.3em;margin-bottom:1em;">Sign In Required</h2>
        <div id="authPopupForms"></div>
        <div id="authPopupError" style="color:#b91c1c;margin-top:1em;display:none;"></div>
      </div>
    `;
    document.body.appendChild(popup);
  }

  function showForm(type) {
    const forms = {
      'pb-user': `<input id="pbUserEmail" type="email" placeholder="Email" style="width:90%;margin-bottom:0.5em;"><br><input id="pbUserPassword" type="password" placeholder="Password" style="width:90%;margin-bottom:0.5em;"><br><button id="authPopupBtn" style="background:#2563eb;color:#fff;padding:0.7em 2em;border:none;border-radius:0.5em;font-size:1em;cursor:pointer;">Sign in</button>`,
      'pb-user-oauth': `<button id="authPopupBtn" style="background:#2563eb;color:#fff;padding:0.7em 2em;border:none;border-radius:0.5em;font-size:1em;cursor:pointer;">Sign in with Microsoft</button>`,
      'pb-superuser': `<input id="pbSuperuserEmail" type="email" placeholder="Superuser Email" style="width:90%;margin-bottom:0.5em;"><br><input id="pbSuperuserPassword" type="password" placeholder="Superuser Password" style="width:90%;margin-bottom:0.5em;"><br><button id="authPopupBtn" style="background:#d97706;color:#fff;padding:0.7em 2em;border:none;border-radius:0.5em;font-size:1em;cursor:pointer;">Sign in as Superuser</button>`,
      'pb-agent': `<input id="pbAgentEmail" type="email" placeholder="Agent Email" style="width:90%;margin-bottom:0.5em;"><br><input id="pbAgentPassword" type="password" placeholder="Agent Password" style="width:90%;margin-bottom:0.5em;"><br><button id="authPopupBtn" style="background:#059669;color:#fff;padding:0.7em 2em;border:none;border-radius:0.5em;font-size:1em;cursor:pointer;">Sign in as Agent</button>`,
      'graph-user': `<button id="authPopupBtn" style="background:#2563eb;color:#fff;padding:0.7em 2em;border:none;border-radius:0.5em;font-size:1em;cursor:pointer;">Sign in with Microsoft</button>`,
      'graph-agent': `<input id="graphAgentEmail" type="email" placeholder="Agent Email" style="width:90%;margin-bottom:0.5em;"><br><input id="graphAgentPassword" type="password" placeholder="Agent Password" style="width:90%;margin-bottom:0.5em;"><br><button id="authPopupBtn" style="background:#059669;color:#fff;padding:0.7em 2em;border:none;border-radius:0.5em;font-size:1em;cursor:pointer;">Sign in as Graph Agent</button>`
    };
    document.getElementById('authPopupForms').innerHTML = forms[type] || '';
  }

  async function promptReauth(type) {
    showForm(type);
    popup.style.display = 'flex';
    return new Promise((resolve, reject) => {
      document.getElementById('authPopupBtn').onclick = async () => {
        try {
          if (type === 'pb-user') {
            const email = document.getElementById('pbUserEmail').value;
            const password = document.getElementById('pbUserPassword').value;
            const authData = await pb.collection('users').authWithPassword(email, password);
            setToken('pb-user', pb.authStore.token);
            popup.style.display = 'none';
            resolve(pb.authStore.token);
          } else if (type === 'pb-user-oauth') {
            const authData = await pb.collection('users').authWithOAuth2({ provider: 'microsoft' });
            setToken('pb-user', authData?.meta?.graphAccessToken || '');
            popup.style.display = 'none';
            resolve(authData?.meta?.graphAccessToken || '');
          } else if (type === 'pb-superuser') {
            superuserCreds.email = document.getElementById('pbSuperuserEmail').value;
            superuserCreds.password = document.getElementById('pbSuperuserPassword').value;
            popup.style.display = 'none';
            resolve();
          } else if (type === 'pb-agent') {
            agentCreds.email = document.getElementById('pbAgentEmail').value;
            agentCreds.password = document.getElementById('pbAgentPassword').value;
            popup.style.display = 'none';
            resolve();
          } else if (type === 'graph-user') {
            const authData = await pb.collection('users').authWithOAuth2({ provider: 'microsoft' });
            setToken('graph-user', authData?.meta?.graphAccessToken || '');
            popup.style.display = 'none';
            resolve(authData?.meta?.graphAccessToken || '');
          } else if (type === 'graph-agent') {
            agentCreds.email = document.getElementById('graphAgentEmail').value;
            agentCreds.password = document.getElementById('graphAgentPassword').value;
            popup.style.display = 'none';
            resolve();
          }
        } catch (err) {
          document.getElementById('authPopupError').textContent = err.message || 'Authentication failed.';
          document.getElementById('authPopupError').style.display = '';
        }
      };
    });
  }

  // --- API ---
  return {
    use,
    getToken,
    setToken,
    clearToken,
    getUserInfo,
    ensureToken,
    refreshToken,
    promptReauth
  };
})();

window.Auth = Auth;

// Example usage:
// Auth.use('pb-graph');
// const token = await Auth.ensureToken('graph');
// const user = Auth.getUserInfo();
// All login prompts are handled via the popup, which is hidden unless needed.
