import { useEffect, useState } from 'react'
import { Link, useNavigate, useSearchParams } from 'react-router-dom'
import { Eye, EyeOff } from 'lucide-react'
import { usePlatformAuth } from '../auth/platform-auth'
import { normalizeNextPath } from '../auth/next-path'
import { PASSWORD_POLICY_HINT, PASSWORD_POLICY_PLACEHOLDER } from '../auth/password-policy'
import {
  getSuperTokensAuthRuntimeValidation,
  isGitHubOAuthEnabled,
  isGoogleOAuthEnabled,
  isOrcidOAuthEnabled,
} from '../auth/supertokens-runtime'
import { SiteMetadata } from '../components/seo/SiteMetadata'
import { compactProductRealityStrip } from '../components/layout/MarketingShell'
import { HyperTwistButton, HyperTwistButtonLink } from '../components/ui/HyperTwistButton'
import { OperationalStatusCallout } from '../components/ui/OperationalStatusCallout'
import { browserDesktopRealityCards, deliverySurfaceCards, desktopWorkflowTracks, operatorManualTracks } from '../site-data'
import { buildSupportPath, getDownloadPlatformLabel, normalizeDownloadPlatform } from '../site-routes'

function AuthShell({
  title,
  subtitle,
  children,
  footer,
}: {
  title: string
  subtitle: string
  children: React.ReactNode
  footer: React.ReactNode
}) {
  return (
    <div className="auth-shell">
      <div className="auth-card">
        <p className="eyebrow">Browser account access</p>
        <h1>{title}</h1>
        <p className="auth-card__subtitle">{subtitle}</p>
        {compactProductRealityStrip}
        {children}
        <div className="auth-card__footer">{footer}</div>
      </div>
    </div>
  )
}

function useNextPath() {
  const [searchParams] = useSearchParams()
  return normalizeNextPath(searchParams.get('next'))
}

type AuthNextStepDescriptor = {
  title: string
  description: string
  bullets: readonly string[]
}

function resolveAuthNextStep(nextPath: string): AuthNextStepDescriptor {
  const [pathname, rawQuery = ''] = nextPath.split('?')
  const searchParams = new URLSearchParams(rawQuery)

  if (pathname === '/app/downloads') {
    const platform = normalizeDownloadPlatform(searchParams.get('platform'))
    const platformLabel = platform ? getDownloadPlatformLabel(platform) : 'desktop'

    return {
      title: `Signed-in ${platformLabel} downloads`,
      description:
        `After sign-in you will continue to the signed-in ${platformLabel} download center so entitlement, current package proof, and release notes stay tied to your account instead of being exposed on an anonymous page.`,
      bullets: [
        `Review the current ${platformLabel} target, package proof, and release notes before download.`,
        'Use the dashboard afterward if you need a desktop-link token for first launch.',
        'Return to notices if rollout or compliance status changes.',
      ],
    }
  }

  if (pathname === '/app/account') {
    return {
      title: 'Signed-in account',
      description:
        'After sign-in you will continue to your account page so session state, plan status, and desktop access continuity can be confirmed before any download or rollout step.',
      bullets: [
        'Confirm your plan, role, and current release access first.',
        'Use the signed-in download center once desktop entitlement is resolved.',
        'Use the dashboard and notices pages if account or release status changes later.',
      ],
    }
  }

  if (pathname === '/app/notices') {
    return {
      title: 'Signed-in notices',
      description:
        'After sign-in you will continue to the signed-in notices page so distribution references, source status, and release details remain attached to your account.',
      bullets: [
        'Review notices before redistributing any covered downloadable build.',
        'Use the signed-in download center when you need the entitled package itself.',
        'Keep account access, native package proof, and legal follow-through synchronized.',
      ],
    }
  }

  return {
    title: 'Signed-in dashboard',
    description:
      'After sign-in you will continue to the signed-in dashboard so browser auth, billing, release status, and desktop-link pairing are resolved before the native simulator takes over.',
    bullets: [
      'Confirm account, plan, and release readiness first.',
      'Open the signed-in download center when you need the entitled desktop build.',
      'Generate a desktop-link token there or from the dashboard before first native launch.',
    ],
  }
}

function AuthNextStepNotice({ nextPath }: { nextPath: string }) {
  const nextStep = resolveAuthNextStep(nextPath)

  return (
    <div className="callout">
      <p className="status-pill status-pill--info">After sign-in</p>
      <p><strong>{nextStep.title}.</strong> {nextStep.description}</p>
      <ul className="list top-gap">
        {nextStep.bullets.map((bullet) => (
          <li key={bullet}>{bullet}</li>
        ))}
      </ul>
    </div>
  )
}

function AuthAccessGuide({ nextPath }: { nextPath: string }) {
  const nextStep = resolveAuthNextStep(nextPath)
  const dashboardCard = deliverySurfaceCards.find((card) => card.title === 'Signed-in dashboard')
  const runtimeCard = deliverySurfaceCards.find((card) => card.title === 'Desktop simulator')
  const pairingTrack = operatorManualTracks.find((track) => track.title === '3. Pair the installed desktop runtime')

  return (
    <div className="card-grid top-gap">
      <article className="card card--compact">
        <h3>{nextStep.title}</h3>
        <p>{nextStep.description}</p>
        <ul className="list top-gap">
          {nextStep.bullets.map((bullet) => (
            <li key={bullet}>{bullet}</li>
          ))}
        </ul>
      </article>
      {dashboardCard ? (
        <article className="card card--compact">
          <h3>{dashboardCard.title}</h3>
          <p>{dashboardCard.description}</p>
          <ul className="list top-gap">
            {dashboardCard.bullets.map((bullet) => (
              <li key={bullet}>{bullet}</li>
            ))}
          </ul>
        </article>
      ) : null}
      {runtimeCard && pairingTrack ? (
        <article className="card card--compact">
          <h3>{runtimeCard.title}</h3>
          <p>{pairingTrack.description}</p>
          <ul className="list top-gap">
            {pairingTrack.steps.map((step) => (
              <li key={step}>{step}</li>
            ))}
          </ul>
        </article>
      ) : null}
    </div>
  )
}

function AuthWorkflowPreview() {
  return (
    <div className="card-grid top-gap">
      <article className="card card--compact">
        <h3>What the desktop runtime is for once you are signed in</h3>
        <p>
          Browser access resolves account, release, and pairing. The actual simulator work still happens in the desktop runtime afterward.
        </p>
      </article>
      {desktopWorkflowTracks.slice(0, 2).map((track) => (
        <article key={track.title} className="card card--compact">
          <h3>{track.title}</h3>
          <p>{track.description}</p>
          <ul className="list top-gap">
            {track.steps.map((step) => (
              <li key={step}>{step}</li>
            ))}
          </ul>
        </article>
      ))}
    </div>
  )
}

function AuthBrowserDesktopRealityPanel() {
  return (
    <div className="top-gap">
      <p className="status-pill status-pill--info">Browser-versus-desktop reality</p>
      <h2>Browser account access does not replace the simulator.</h2>
      <p>
        Sign-in exists so protected release, entitlement, pairing, and account work can stay in the browser.
        The real simulator still lives in the desktop runtime, and headset/controller validation stays explicit.
      </p>
      <div className="card-grid top-gap">
        {browserDesktopRealityCards.map((card) => (
          <article key={card.title} className="card card--compact">
            <p className="status-pill status-pill--info">{card.posture}</p>
            <h3>{card.title}</h3>
            <p>{card.description}</p>
            <ul className="list top-gap">
              {card.bullets.map((bullet) => (
                <li key={bullet}>{bullet}</li>
              ))}
            </ul>
          </article>
        ))}
      </div>
    </div>
  )
}

function AuthRuntimeNotice() {
  const authRuntimeValidation = getSuperTokensAuthRuntimeValidation()
  if (authRuntimeValidation.ready && authRuntimeValidation.warnings.length === 0) {
    return null
  }

  const diagnostics = [
    ...authRuntimeValidation.missing.map((item) => `Auth runtime setting pending: ${item}`),
    ...authRuntimeValidation.warnings,
  ]

  return (
    <OperationalStatusCallout
      badge={authRuntimeValidation.ready ? 'Auth launch notice' : 'Auth recovery mode'}
      title={
        authRuntimeValidation.ready
          ? 'Account access is available while launch configuration is being finalized.'
          : 'Account access can continue through the available browser-auth lane.'
      }
      summary={
        authRuntimeValidation.ready
          ? 'You can still sign in, create an account, and continue into your dashboard, downloads, and desktop pairing flow.'
          : 'If shared auth is temporarily unavailable, HyperTwist still keeps account routing recoverable so you can review access, downloads, and support paths.'
      }
      sections={[
        {
          title: 'What still works',
          items: [
            'Login, registration, and safe next-step routing remain available.',
            'The dashboard can still recover your account, release, and desktop-pairing status after sign-in.',
          ],
        },
        {
          title: 'What may still need follow-through',
          items: [
            'Some shared-auth or billing details may still need finishing work before this deployment is fully launch-ready.',
          ],
        },
        {
          title: 'Runtime diagnostics',
          items: diagnostics,
        },
        {
          title: 'Best next step',
          items: [
            authRuntimeValidation.ready
              ? 'Continue into the dashboard for account status, downloads, and desktop pairing.'
              : 'Create an account for orientation now, then contact support if you need release access immediately.',
          ],
        },
      ]}
      actions={[
        { label: 'Open support', to: buildSupportPath('operator-access') },
        { label: 'Review download access', to: '/download' },
      ]}
    />
  )
}

export function LoginPage() {
  const navigate = useNavigate()
  const { login, isAuthenticated } = usePlatformAuth()
  const nextPath = useNextPath()
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [error, setError] = useState('')
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [showPassword, setShowPassword] = useState(false)
  const [oauthLoading, setOauthLoading] = useState<'google' | 'github' | 'orcid' | null>(null)

  useEffect(() => {
    if (isAuthenticated) {
      navigate(nextPath, { replace: true })
    }
  }, [isAuthenticated, navigate, nextPath])

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault()
    setIsSubmitting(true)
    setError('')
    const result = await login({ method: 'email', email, password })
    setIsSubmitting(false)
    if (!result.ok) {
      setError(result.error || 'Unable to sign in.')
      return
    }
    navigate(nextPath, { replace: true })
  }

  async function handleOAuth(provider: 'google' | 'github' | 'orcid') {
    setError('')
    setOauthLoading(provider)
    try {
      const result = await login({ method: provider, email: '' })
      if (result?.ok === false) {
        setError(result.error || 'Unable to continue with the selected identity provider.')
        setOauthLoading(null)
        return
      }
      setOauthLoading(null)
    } catch {
      setError('Unable to continue with the selected identity provider.')
      setOauthLoading(null)
    }
  }

  return (
    <>
      <SiteMetadata
        title="Log in to HyperTwist"
        description="Log in to HyperTwist to open the browser dashboard, review release access, and pair the desktop runtime to your account."
        canonicalPath="/login"
        robots="noindex,nofollow"
      />
      <AuthShell
        title="Log in to HyperTwist"
        subtitle="Sign in to reach your dashboard, desktop downloads, release notes, and first-launch pairing tools."
        footer={<p>Need access? <Link to={`/register?next=${encodeURIComponent(nextPath)}`}>Create an account</Link>.</p>}
      >
        <AuthRuntimeNotice />
        <AuthNextStepNotice nextPath={nextPath} />
        <form className="auth-form" onSubmit={handleSubmit}>
          <label className="input-label" htmlFor="login-email">Email</label>
          <input
            id="login-email"
            className="input"
            type="email"
            autoComplete="email"
            required
            value={email}
            onChange={(event) => setEmail(event.target.value)}
          />
          <label className="input-label" htmlFor="login-password">Password</label>
          <div className="input-with-action">
            <input
              id="login-password"
              className="input"
              type={showPassword ? 'text' : 'password'}
              autoComplete="current-password"
              required
              value={password}
              onChange={(event) => setPassword(event.target.value)}
            />
            <button
              type="button"
              className="input-action"
              aria-label={showPassword ? 'Hide password' : 'Show password'}
              onClick={() => setShowPassword((current) => !current)}
            >
              {showPassword ? <EyeOff size={17} /> : <Eye size={17} />}
            </button>
          </div>
          {error ? <p className="form-error">{error}</p> : null}
          <HyperTwistButton full disabled={isSubmitting} type="submit">
            {isSubmitting ? 'Signing in...' : 'Log in'}
          </HyperTwistButton>
          <div className="button-row top-gap">
            <HyperTwistButtonLink full tone="secondary" to={`/register?next=${encodeURIComponent(nextPath)}`}>
              Create account
            </HyperTwistButtonLink>
            <HyperTwistButtonLink full tone="ghost" to="/browser">
              Learn how the website and desktop app work together
            </HyperTwistButtonLink>
          </div>
        </form>
        <div className="provider-row">
          {isGoogleOAuthEnabled() ? (
            <HyperTwistButton full tone="ghost" disabled={oauthLoading !== null} type="button" onClick={() => void handleOAuth('google')}>
              {oauthLoading === 'google' ? 'Redirecting to Google...' : 'Continue with Google'}
            </HyperTwistButton>
          ) : null}
          {isGitHubOAuthEnabled() ? (
            <HyperTwistButton full tone="ghost" disabled={oauthLoading !== null} type="button" onClick={() => void handleOAuth('github')}>
              {oauthLoading === 'github' ? 'Redirecting to GitHub...' : 'Continue with GitHub'}
            </HyperTwistButton>
          ) : null}
          {isOrcidOAuthEnabled() ? (
            <HyperTwistButton full tone="ghost" disabled={oauthLoading !== null} type="button" onClick={() => void handleOAuth('orcid')}>
              {oauthLoading === 'orcid' ? 'Redirecting to ORCID...' : 'Continue with ORCID'}
            </HyperTwistButton>
          ) : null}
        </div>
        <AuthBrowserDesktopRealityPanel />
        <AuthAccessGuide nextPath={nextPath} />
        <AuthWorkflowPreview />
      </AuthShell>
    </>
  )
}

export function RegisterPage() {
  const navigate = useNavigate()
  const { login, register, isAuthenticated } = usePlatformAuth()
  const nextPath = useNextPath()
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [name, setName] = useState('')
  const [error, setError] = useState('')
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [showPassword, setShowPassword] = useState(false)
  const [oauthLoading, setOauthLoading] = useState<'google' | 'github' | 'orcid' | null>(null)

  useEffect(() => {
    if (isAuthenticated) {
      navigate(nextPath, { replace: true })
    }
  }, [isAuthenticated, navigate, nextPath])

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault()
    setIsSubmitting(true)
    setError('')
    const result = await register({ method: 'email', email, password, name })
    setIsSubmitting(false)
    if (!result.ok) {
      setError(result.error || 'Unable to create your account.')
      return
    }
    navigate(nextPath, { replace: true })
  }

  async function handleOAuth(provider: 'google' | 'github' | 'orcid') {
    setError('')
    setOauthLoading(provider)
    try {
      const result = await login({ method: provider, email: '' })
      if (result?.ok === false) {
        setError(result.error || 'Unable to continue with the selected identity provider.')
        setOauthLoading(null)
        return
      }
      setOauthLoading(null)
    } catch {
      setError('Unable to continue with the selected identity provider.')
      setOauthLoading(null)
    }
  }

  return (
    <>
      <SiteMetadata
        title="Create a HyperTwist account"
        description="Create a HyperTwist account to unlock the browser dashboard, release status, and desktop-link pairing for the desktop simulator lane."
        canonicalPath="/register"
        robots="noindex,nofollow"
      />
      <AuthShell
        title="Create a HyperTwist account"
        subtitle="Create your account to unlock the dashboard, desktop downloads, release notes, and browser-to-desktop pairing."
        footer={<p>Already have access? <Link to={`/login?next=${encodeURIComponent(nextPath)}`}>Log in</Link>.</p>}
      >
        <AuthRuntimeNotice />
        <AuthNextStepNotice nextPath={nextPath} />
        <form className="auth-form" onSubmit={handleSubmit}>
          <label className="input-label" htmlFor="register-name">Name</label>
          <input
            id="register-name"
            className="input"
            type="text"
            autoComplete="name"
            value={name}
            onChange={(event) => setName(event.target.value)}
          />
          <label className="input-label" htmlFor="register-email">Email</label>
          <input
            id="register-email"
            className="input"
            type="email"
            autoComplete="email"
            required
            value={email}
            onChange={(event) => setEmail(event.target.value)}
          />
          <label className="input-label" htmlFor="register-password">Password</label>
          <div className="input-with-action">
            <input
              id="register-password"
              className="input"
              type={showPassword ? 'text' : 'password'}
              autoComplete="new-password"
              required
              minLength={8}
              placeholder={PASSWORD_POLICY_PLACEHOLDER}
              value={password}
              onChange={(event) => setPassword(event.target.value)}
            />
            <button
              type="button"
              className="input-action"
              aria-label={showPassword ? 'Hide password' : 'Show password'}
              onClick={() => setShowPassword((current) => !current)}
            >
              {showPassword ? <EyeOff size={17} /> : <Eye size={17} />}
            </button>
          </div>
          <p className="input-help">{PASSWORD_POLICY_HINT}</p>
          {error ? <p className="form-error">{error}</p> : null}
          <HyperTwistButton full disabled={isSubmitting} type="submit">
            {isSubmitting ? 'Creating account...' : 'Create account'}
          </HyperTwistButton>
          <div className="button-row top-gap">
            <HyperTwistButtonLink full tone="secondary" to={`/login?next=${encodeURIComponent(nextPath)}`}>
              Already have an account? Log in
            </HyperTwistButtonLink>
            <HyperTwistButtonLink full tone="ghost" to="/pricing">
              Compare plans first
            </HyperTwistButtonLink>
          </div>
        </form>
        <div className="provider-row">
          {isGoogleOAuthEnabled() ? (
            <HyperTwistButton full tone="ghost" disabled={oauthLoading !== null} type="button" onClick={() => void handleOAuth('google')}>
              {oauthLoading === 'google' ? 'Redirecting to Google...' : 'Continue with Google'}
            </HyperTwistButton>
          ) : null}
          {isGitHubOAuthEnabled() ? (
            <HyperTwistButton full tone="ghost" disabled={oauthLoading !== null} type="button" onClick={() => void handleOAuth('github')}>
              {oauthLoading === 'github' ? 'Redirecting to GitHub...' : 'Continue with GitHub'}
            </HyperTwistButton>
          ) : null}
          {isOrcidOAuthEnabled() ? (
            <HyperTwistButton full tone="ghost" disabled={oauthLoading !== null} type="button" onClick={() => void handleOAuth('orcid')}>
              {oauthLoading === 'orcid' ? 'Redirecting to ORCID...' : 'Continue with ORCID'}
            </HyperTwistButton>
          ) : null}
        </div>
        <AuthBrowserDesktopRealityPanel />
        <AuthAccessGuide nextPath={nextPath} />
        <AuthWorkflowPreview />
      </AuthShell>
    </>
  )
}
