'use client';

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import type { MDXRemoteSerializeResult } from 'next-mdx-remote';
import AppHeader from '@/components/AppHeader';
import DocsSidebar, { type DocsManifest } from '@/components/DocsSidebar';
import DocsTOC, { type Heading } from '@/components/DocsTOC';
import DocsContent from '@/components/DocsContent';
import { useIsMobile } from '@/lib/useIsMobile';
import { useTranslation } from '@/lib/i18n';
import { getEmail, isAuthenticated, logout } from '@/lib/auth';

type ContentResponse = {
  slug: string;
  title: string;
  description: string;
  fallback: boolean;
  headings: Heading[];
  source: MDXRemoteSerializeResult;
};

interface DocsShellProps {
  /** Slug parts from the URL, empty array for /docs (index). */
  slugParts: string[];
}

function FallbackBanner({ message }: { message: string }) {
  return (
    <div style={{
      background: '#fffbeb',
      border: '1px solid #fde68a',
      borderRadius: '10px',
      padding: '10px 14px',
      fontSize: '13px',
      color: '#92400e',
      marginBottom: '20px',
      display: 'flex',
      alignItems: 'center',
      gap: '8px',
    }}>
      <span style={{ flexShrink: 0 }}>ℹ</span>
      <span>{message}</span>
    </div>
  );
}

function NotFoundCard() {
  const { t } = useTranslation();
  const router = useRouter();
  return (
    <div style={{
      background: '#fff',
      border: '1px solid #eee',
      borderRadius: '14px',
      padding: '40px 28px',
      textAlign: 'center',
    }}>
      <div style={{ fontSize: '40px', marginBottom: '12px' }}>📭</div>
      <h2 style={{ fontSize: '20px', fontWeight: 700, color: '#1a1a2e', margin: '0 0 8px' }}>
        {t('docs.notFoundTitle')}
      </h2>
      <p style={{ fontSize: '14px', color: '#666', margin: '0 0 18px' }}>
        {t('docs.notFoundDescription')}
      </p>
      <button
        onClick={() => router.push('/docs')}
        style={{
          padding: '8px 18px',
          background: 'linear-gradient(135deg, #5c5fbc, #7c7fdc)',
          border: 'none',
          borderRadius: '8px',
          color: '#fff',
          fontSize: '13.5px',
          fontWeight: 600,
          cursor: 'pointer',
        }}
      >
        {t('docs.notFoundBack')}
      </button>
    </div>
  );
}

function ContentSkeleton() {
  return (
    <div>
      <div style={{ height: '32px', width: '60%', background: '#eee', borderRadius: '6px', marginBottom: '14px' }} />
      <div style={{ height: '16px', width: '90%', background: '#f0f0f0', borderRadius: '4px', marginBottom: '24px' }} />
      {[85, 70, 95, 60, 80, 50].map((w, i) => (
        <div key={i} style={{ height: '13px', width: `${w}%`, background: '#f4f4f4', borderRadius: '4px', marginBottom: '10px' }} />
      ))}
    </div>
  );
}

export default function DocsShell({ slugParts }: DocsShellProps) {
  const router = useRouter();
  const { t, locale } = useTranslation();
  const isMobile = useIsMobile();
  const slug = slugParts.length === 0 ? 'index' : slugParts.join('/');

  const [email, setEmail] = useState<string | null>(null);
  const [manifest, setManifest] = useState<DocsManifest | null>(null);
  const [content, setContent] = useState<ContentResponse | null>(null);
  const [contentStatus, setContentStatus] = useState<'loading' | 'ok' | 'not-found' | 'error'>('loading');
  const [isWide, setIsWide] = useState(false);

  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setEmail(isAuthenticated() ? getEmail() : null);
  }, []);

  // Track the >= 1100px breakpoint reactively so the right-side ToC appears
  // and disappears on resize without needing a full re-render trigger.
  useEffect(() => {
    if (typeof window === 'undefined') return;
    const mql = window.matchMedia('(min-width: 1100px)');
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setIsWide(mql.matches);
    const onChange = (e: MediaQueryListEvent) => setIsWide(e.matches);
    mql.addEventListener('change', onChange);
    return () => mql.removeEventListener('change', onChange);
  }, []);

  useEffect(() => {
    let cancelled = false;
    fetch(`/docs/manifest?locale=${locale}`, { cache: 'no-store' })
      .then(r => (r.ok ? r.json() : Promise.reject(r)))
      .then(data => {
        if (!cancelled) setManifest(data as DocsManifest);
      })
      .catch(() => {
        if (!cancelled) setManifest(null);
      });
    return () => {
      cancelled = true;
    };
  }, [locale]);

  useEffect(() => {
    let cancelled = false;
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setContentStatus('loading');
    setContent(null);
    fetch(`/docs/content?locale=${locale}&slug=${encodeURIComponent(slug)}`, { cache: 'no-store' })
      .then(r => {
        if (r.status === 404) {
          if (!cancelled) {
            setContentStatus('not-found');
          }
          return null;
        }
        if (!r.ok) {
          if (!cancelled) setContentStatus('error');
          return null;
        }
        return r.json();
      })
      .then(data => {
        if (cancelled || !data) return;
        setContent(data as ContentResponse);
        setContentStatus('ok');
      })
      .catch(() => {
        if (!cancelled) setContentStatus('error');
      });
    return () => {
      cancelled = true;
    };
  }, [locale, slug]);

  const handleLogout = async () => {
    await logout();
    router.replace('/login');
  };

  // Layout: AppHeader + grid (sidebar + content + ToC)
  const desktopGrid: React.CSSProperties = {
    display: 'grid',
    gridTemplateColumns: '260px minmax(0, 1fr) 240px',
    gap: '40px',
    maxWidth: '1280px',
    margin: '0 auto',
    padding: '0 40px',
  };

  const tabletGrid: React.CSSProperties = {
    display: 'grid',
    gridTemplateColumns: '240px minmax(0, 1fr)',
    gap: '32px',
    maxWidth: '1100px',
    margin: '0 auto',
    padding: '0 32px',
  };

  const showToC = !isMobile && isWide;

  return (
    <div style={{ minHeight: '100vh', background: '#fff' }}>
      <AppHeader
        activePage="docs"
        email={email}
        isMobile={isMobile}
        onSettings={() => {/* docs page does not surface settings */}}
        onLogout={handleLogout}
      />

      {isMobile ? (
        <div style={{ padding: '12px 0 0' }}>
          <DocsSidebar manifest={manifest} activeSlug={slug} isMobile />
          <div style={{ padding: '0 16px 40px' }}>
            <ContentArea
              contentStatus={contentStatus}
              content={content}
              fallbackMessage={t('docs.fallbackNotice')}
            />
          </div>
        </div>
      ) : (
        <div style={showToC ? desktopGrid : tabletGrid}>
          <DocsSidebar manifest={manifest} activeSlug={slug} isMobile={false} />
          <main style={{ padding: '24px 0 64px', minWidth: 0, maxWidth: '760px' }}>
            <ContentArea
              contentStatus={contentStatus}
              content={content}
              fallbackMessage={t('docs.fallbackNotice')}
            />
          </main>
          {showToC && (
            <DocsTOC headings={content?.headings ?? []} />
          )}
        </div>
      )}
    </div>
  );
}

function ContentArea({
  contentStatus,
  content,
  fallbackMessage,
}: {
  contentStatus: 'loading' | 'ok' | 'not-found' | 'error';
  content: ContentResponse | null;
  fallbackMessage: string;
}) {
  const { t } = useTranslation();

  if (contentStatus === 'loading') {
    return <ContentSkeleton />;
  }

  if (contentStatus === 'not-found') {
    return <NotFoundCard />;
  }

  if (contentStatus === 'error' || !content) {
    return (
      <div style={{
        fontSize: '14px',
        color: '#b91c1c',
        background: '#fef2f2',
        border: '1px solid #fecaca',
        borderRadius: '12px',
        padding: '14px 16px',
      }}>
        {t('docs.loadFailed')}
      </div>
    );
  }

  return (
    <>
      {content.fallback && <FallbackBanner message={fallbackMessage} />}
      <header style={{ marginBottom: '16px' }}>
        <h1 style={{
          fontSize: '32px',
          fontWeight: 800,
          color: '#1a1a2e',
          margin: 0,
          letterSpacing: '-0.5px',
        }}>
          {content.title}
        </h1>
        {content.description && (
          <p style={{ fontSize: '15px', color: '#666', margin: '8px 0 0', lineHeight: 1.6 }}>
            {content.description}
          </p>
        )}
      </header>
      <DocsContent source={content.source} />
    </>
  );
}
