<script>
  import '../app.css';
  import { Home, Settings, History, Github, Menu } from 'lucide-svelte';
  import { onMount } from 'svelte';

  let currentPage = 'tts';
  let sidebarOpen = true;

  // Initialize from cache immediately to avoid "Checking..." flash
  const initToken = typeof window !== 'undefined' ? localStorage.getItem('hf_access_token') : null;
  const initCachedToken =
    typeof window !== 'undefined' ? localStorage.getItem('hf_cached_token') : null;
  const initCachedUserInfo =
    typeof window !== 'undefined' ? localStorage.getItem('hf_user_info') : null;

  let isLoggedIn = false;
  let username = '';
  let isCheckingAuth = false; // Start as false by default

  // Check if we have valid cached data
  let hasCachedData = false;
  if (initToken && initToken === initCachedToken && initCachedUserInfo) {
    try {
      const userInfo = JSON.parse(initCachedUserInfo);
      isLoggedIn = true;
      username = userInfo.username;
      hasCachedData = true;
    } catch (e) {
      // Invalid cache, will need to check
      isCheckingAuth = true;
    }
  } else if (initToken) {
    // We have a token but no valid cache, need to check
    isCheckingAuth = true;
  }

  let showTokenInput = false;
  let tokenInput = '';
  let tokenError = '';
  let isLocalEnvironment = false;
  let showSignInPopover = false;

  onMount(() => {
    window.addEventListener('show-signin-popover', () => {
      showSignInPopover = true;
      setTimeout(() => {
        showSignInPopover = false;
      }, 4000);
    });

    // Only check if we don't already have valid cached info or need to verify
    if (!hasCachedData && initToken) {
      checkLocalTokenAvailability();
      checkLoginStatus();
    } else if (!initToken) {
      // No token at all, check for local availability
      checkLocalTokenAvailability();
    }

    document.addEventListener('visibilitychange', () => {
      if (!document.hidden) {
        checkLoginStatus();
      }
    });

    window.addEventListener('storage', checkLoginStatus);

    const interval = setInterval(checkLoginStatus, 1000);

    return () => {
      window.removeEventListener('storage', checkLoginStatus);
      clearInterval(interval);
    };
  });

  async function checkLocalTokenAvailability() {
    // Skip if we already have valid cached info
    if (isLoggedIn && hasCachedData) {
      return;
    }

    isCheckingAuth = true;

    try {
      const response = await fetch('/api/auth/local-token');
      const data = await response.json();

      if (data.available) {
        isLocalEnvironment = true;
        localStorage.setItem('hf_access_token', data.token);

        if (data.user_info && data.user_info.name !== 'Local User') {
          isLoggedIn = true;
          username = data.user_info.name.split(' ')[0];
        } else {
          isLoggedIn = true;
          username = 'Local User';
        }
      } else {
        isLocalEnvironment = false;
      }
    } catch (error) {
      isLocalEnvironment = false;
    } finally {
      isCheckingAuth = false;
    }
  }

  function checkLoginStatus() {
    const token = localStorage.getItem('hf_access_token');
    const cachedUserInfo = localStorage.getItem('hf_user_info');
    const cachedToken = localStorage.getItem('hf_cached_token');

    if (token) {
      // If token hasn't changed and we have cached info, use it
      if (token === cachedToken && cachedUserInfo) {
        try {
          const userInfo = JSON.parse(cachedUserInfo);
          isLoggedIn = true;
          username = userInfo.username;
          return;
        } catch (e) {
          // Invalid cache, will re-fetch
        }
      }
      // Token is new or changed, fetch user info
      if (!isLoggedIn || token !== cachedToken) {
        fetchUserInfo(token);
      }
    } else {
      // No token, clear everything
      isLoggedIn = false;
      username = '';
      localStorage.removeItem('hf_user_info');
      localStorage.removeItem('hf_cached_token');
    }
  }

  async function fetchUserInfo(token) {
    isCheckingAuth = true;

    try {
      const response = await fetch('https://huggingface.co/api/whoami-v2', {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });

      if (response.ok) {
        const userData = await response.json();
        isLoggedIn = true;
        const fullName =
          userData.name || userData.fullname || userData.login || userData.username || 'User';
        username = fullName.split(' ')[0];

        // Cache the user info and token
        const userInfo = { username, fullName };
        localStorage.setItem('hf_user_info', JSON.stringify(userInfo));
        localStorage.setItem('hf_cached_token', token);
      } else {
        // Clear everything on auth failure
        localStorage.removeItem('hf_access_token');
        localStorage.removeItem('hf_user_info');
        localStorage.removeItem('hf_cached_token');
        isLoggedIn = false;
        username = '';
      }
    } catch (error) {
      // On network error, if we have cached info, use it
      const cachedUserInfo = localStorage.getItem('hf_user_info');
      if (cachedUserInfo) {
        try {
          const userInfo = JSON.parse(cachedUserInfo);
          isLoggedIn = true;
          username = userInfo.username;
          return;
        } catch (e) {
          // Invalid cache
        }
      }
      // Otherwise clear everything
      localStorage.removeItem('hf_access_token');
      localStorage.removeItem('hf_user_info');
      localStorage.removeItem('hf_cached_token');
      isLoggedIn = false;
      username = '';
    } finally {
      isCheckingAuth = false;
    }
  }

  async function handleAuthAction() {
    if (isLoggedIn) {
      localStorage.removeItem('hf_access_token');
      localStorage.removeItem('hf_user_info');
      localStorage.removeItem('hf_cached_token');
      sessionStorage.removeItem('oauth_state');
      isLoggedIn = false;
      username = '';
    } else {
      if (
        window.location.hostname.includes('hf.space') ||
        window.location.hostname.includes('huggingface.co')
      ) {
        try {
          const response = await fetch('/api/auth/oauth-config');
          const config = await response.json();
          const scopes = config.scopes || 'read-repos write-repos manage-repos inference-api';
          const oauthUrl = `https://huggingface.co/oauth/authorize?client_id=${config.client_id}&redirect_uri=${encodeURIComponent(window.location.origin + '/auth/callback')}&scope=${encodeURIComponent(scopes)}&response_type=code&state=${Date.now()}`;
          window.location.href = oauthUrl;
        } catch (error) {
          showTokenInput = true;
          tokenInput = '';
          tokenError = '';
        }
      } else {
        showTokenInput = true;
        tokenInput = '';
        tokenError = '';
      }
    }
  }

  function closeTokenInput() {
    showTokenInput = false;
    tokenInput = '';
    tokenError = '';
  }

  async function submitToken() {
    if (!tokenInput.trim()) {
      tokenError = 'Please enter a token';
      return;
    }

    if (!tokenInput.startsWith('hf_')) {
      tokenError = 'Token should start with "hf_"';
      return;
    }

    try {
      const response = await fetch('https://huggingface.co/api/whoami-v2', {
        headers: {
          Authorization: `Bearer ${tokenInput.trim()}`,
        },
      });

      if (response.ok) {
        const userData = await response.json();
        const token = tokenInput.trim();
        localStorage.setItem('hf_access_token', token);
        isLoggedIn = true;
        const fullName =
          userData.name || userData.fullname || userData.login || userData.username || 'User';
        username = fullName.split(' ')[0];

        // Cache the user info and token
        const userInfo = { username, fullName };
        localStorage.setItem('hf_user_info', JSON.stringify(userInfo));
        localStorage.setItem('hf_cached_token', token);

        closeTokenInput();
      } else {
        tokenError = `Invalid token (${response.status}). Please check your token and try again.`;
      }
    } catch (error) {
      tokenError = 'Error validating token. Please try again.';
    }
  }
</script>

<div class="flex h-screen bg-white">
  <!-- Sidebar -->
  <aside
    class="w-56 border-r border-gray-200 bg-white flex-shrink-0 flex flex-col h-full {sidebarOpen
      ? ''
      : 'hidden'}"
  >
    <div class="p-4 border-b border-gray-200">
      <div class="flex items-center gap-3">
        <img src="/assets/hf-studio-logo.png" alt="HF Logo" class="w-8 h-8" />
        <h1 class="text-xl font-semibold">
          HFStudio<sup class="text-xs text-gray-500 ml-1">BETA</sup>
        </h1>
      </div>
    </div>

    <nav class="p-2 text-sm flex-1">
      <div class="mt-2 mb-1 px-2 text-xs font-medium text-gray-500 uppercase">Tasks</div>

      <button
        class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-gray-100 transition-colors text-left
               {currentPage === 'tts' ? 'bg-gray-100' : ''}"
        on:click={() => (currentPage = 'tts')}
      >
        <span>🎙️</span>
        <span>Text to Speech</span>
      </button>

      <button
        class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
        disabled
      >
        <span>🎵</span>
        <span>Voice Cloning</span>
      </button>

      <button
        class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
        disabled
      >
        <span>🎧</span>
        <span>Speech to Text</span>
      </button>

      <button
        class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
        disabled
      >
        <span>🎼</span>
        <span>Sound Effects</span>
      </button>

      <button
        class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
        disabled
      >
        <span>🎸</span>
        <span>Music Generation</span>
      </button>

      <button
        class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
        disabled
      >
        <span>🔊</span>
        <span>Audio Enhancement</span>
      </button>
    </nav>

    <!-- Sign in with Hugging Face at bottom -->
    <div class="p-2 relative">
      <button
        on:click={handleAuthAction}
        disabled={isCheckingAuth}
        class="w-full px-6 py-3 bg-black text-white rounded-lg font-medium hover:bg-gray-800 transition-colors shadow-sm flex items-center justify-center gap-2 text-sm disabled:opacity-50 disabled:cursor-not-allowed"
      >
        <img src="/assets/hf-logo.png" alt="HF Logo" class="w-5 h-5" />
        {#if isCheckingAuth}
          <span>Checking... ({isLoggedIn ? 'logged in' : 'not logged in'})</span>
        {:else if isLoggedIn}
          <span>Sign out ({username})</span>
        {:else}
          <span>Sign In</span>
        {/if}
      </button>

      <!-- Sign In Popover -->
      {#if showSignInPopover && !isLoggedIn}
        <div class="absolute bottom-full left-0 right-0 mb-2 z-50">
          <div class="bg-blue-600 text-white text-sm rounded-lg p-3 shadow-lg relative">
            <div class="flex items-start gap-2">
              <svg class="w-4 h-4 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
                <path
                  fill-rule="evenodd"
                  d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
                  clip-rule="evenodd"
                />
              </svg>
              <div>
                <p class="font-medium">Sign in required</p>
                <p class="text-blue-100 text-xs mt-1">
                  You need to sign in to use HuggingFace Inference Providers for text-to-speech
                  generation.
                </p>
              </div>
            </div>
            <!-- Arrow pointing down -->
            <div class="absolute top-full left-1/2 transform -translate-x-1/2">
              <div
                class="w-0 h-0 border-l-4 border-r-4 border-t-4 border-l-transparent border-r-transparent border-t-blue-600"
              ></div>
            </div>
          </div>
        </div>
      {/if}
    </div>
  </aside>

  <!-- Main content -->
  <main class="flex-1 overflow-auto">
    <slot />
  </main>

  <!-- Token Input Modal -->
  {#if showTokenInput}
    <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
      <div class="bg-white rounded-lg p-6 max-w-md w-full mx-4 shadow-xl">
        <h2 class="text-xl font-semibold mb-4">Sign In with HuggingFace Token</h2>

        <div class="mb-4 p-3 bg-blue-50 rounded-md text-sm">
          <p class="text-blue-800 mb-2">
            <strong>Manual Token Entry:</strong> Please enter your HuggingFace token.
          </p>
          <p class="text-blue-700">
            1. Go to <a
              href="https://huggingface.co/settings/tokens"
              target="_blank"
              class="underline text-blue-600">HuggingFace Settings</a
            ><br />
            2. Create a new token with "Inference API" permissions<br />
            3. Copy and paste it below
          </p>
          {#if isLocalEnvironment}
            <p class="text-blue-600 mt-2">
              <strong>Tip:</strong> You can also run <code>huggingface-cli login</code> in your terminal
              to automatically use your local token.
            </p>
          {/if}
        </div>

        <div class="mb-4">
          <label for="token" class="block text-sm font-medium text-gray-700 mb-2">
            HuggingFace Token
          </label>
          <input
            id="token"
            type="password"
            bind:value={tokenInput}
            placeholder="hf_..."
            class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent"
            on:keydown={(e) => e.key === 'Enter' && submitToken()}
          />
          {#if tokenError}
            <p class="text-red-600 text-sm mt-1">{tokenError}</p>
          {/if}
        </div>

        <div class="flex justify-end gap-3">
          <button
            on:click={closeTokenInput}
            class="px-4 py-2 text-gray-600 hover:text-gray-800 transition-colors"
          >
            Cancel
          </button>
          <button
            on:click={submitToken}
            class="px-4 py-2 bg-orange-500 text-white rounded-md hover:bg-orange-600 transition-colors"
          >
            Sign In
          </button>
        </div>
      </div>
    </div>
  {/if}
</div>
