'use client';

import Link from 'next/link';
import { useEffect, useMemo, useRef, useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useMediaCatalog, getSceneStageBackgroundStyle } from '@/entities/media';
import { usePlanTier } from '@/entities/plan';
import { getSceneById, SCENE_THEMES } from '@/entities/scene';
import { SOUND_PRESETS } from '@/entities/session';
import { PaywallSheetContent } from '@/features/paywall-sheet';
import { focusSessionApi, type FocusSession } from '@/features/focus-session/api/focusSessionApi';
import { useFocusStats, type ReviewCarryHint } from '@/features/stats';
import { copy } from '@/shared/i18n';
import { cn } from '@/shared/lib/cn';
import {
  ATMOSPHERE_OPTIONS,
  ENTRY_DURATION_SUGGESTIONS,
  findAtmosphereOptionForSelection,
  getAtmosphereOptionById,
  getRecommendedDurationMinutes,
  getTimerPresetMetaById,
  parseDurationMinutes,
  resolveNearestTimerPreset,
  sanitizeDurationDraft,
} from '../model/atmosphereEntry';
import { AppAtmosphereEntryShell } from './AppAtmosphereEntryShell';

const DEFAULT_SCENE_ID = getSceneById('forest')?.id ?? SCENE_THEMES[0].id;
const DEFAULT_SOUND_ID = SOUND_PRESETS.find((preset) => preset.id === 'forest-birds')?.id ?? SOUND_PRESETS[0].id;
const DEFAULT_TIMER_ID = '50-10';
const REVIEW_ENTRY_PRESETS = {
  'forest-50-10': {
    sceneId: DEFAULT_SCENE_ID,
    soundPresetId: DEFAULT_SOUND_ID,
    timerPresetId: DEFAULT_TIMER_ID,
    label: '숲 · Forest Birds',
  },
} as const;
const DEFAULT_ATMOSPHERE =
  findAtmosphereOptionForSelection(DEFAULT_SCENE_ID, DEFAULT_SOUND_ID) ?? ATMOSPHERE_OPTIONS[0];

const entryCopy = {
  eyebrow: 'VibeRoom',
  goalPlaceholder: 'e.g. Write the first draft',
  durationLabel: 'Estimated Time',
  durationPlaceholder: 'e.g. 70',
  durationHelper: 'Set a realistic time to accomplish this goal.',
  startNow: 'Begin Session',
  startLoading: 'Entering...',
  atmosphereTitle: 'Atmosphere',
  atmosphereBody:
    'Background and sound play together. Choose an atmosphere to dive into deep focus.',
  loadFailed: 'Failed to load session state. You can still start a new one.',
  reviewEyebrow: 'Weekly Review',
  reviewTitle: 'Take a quick look at your weekly review?',
  reviewCta: 'View Review',
  reviewHelper: 'A brief look back before you start.',
  reviewTitlePro: 'Revisit a flow that worked well for you?',
  reviewCtaPro: 'View My Flow',
  reviewHelperPro: 'Check your best rituals and carry-forwards.',
  reviewReturnEyebrow: 'From your recent review',
  reviewReturnTitleSteady: 'Keep the rhythm that worked well this week.',
  reviewReturnTitleSmaller: 'Try setting a smaller goal this time.',
  reviewReturnTitleClosure: 'Decide where to wrap up before you start.',
  reviewReturnTitleStart: 'Your focus right now: just start one more session.',
  reviewReturnBodySteady: 'Set your own goal, but maintain the light entry rhythm.',
  reviewReturnBodySmaller: 'Instead of extending time, a smaller goal makes it easier to keep going.',
  reviewReturnBodyClosure: 'Think about where to close the block first to finish strong.',
  reviewReturnBodyStart: 'Just aim to open one more short session to build momentum.',
  reviewReturnRitualLabel: 'Recommended Ritual · Forest · Forest Birds',
  paywallLead: 'Calm Session OS PRO',
  paywallBody: 'Pro enables faster rituals and deeper reviews for seamless entry and return.',
};

const reviewCarryCopyByHint: Record<
  ReviewCarryHint,
  { title: string; body: string }
> = {
  steady: {
    title: entryCopy.reviewReturnTitleSteady,
    body: entryCopy.reviewReturnBodySteady,
  },
  smaller: {
    title: entryCopy.reviewReturnTitleSmaller,
    body: entryCopy.reviewReturnBodySmaller,
  },
  closure: {
    title: entryCopy.reviewReturnTitleClosure,
    body: entryCopy.reviewReturnBodyClosure,
  },
  start: {
    title: entryCopy.reviewReturnTitleStart,
    body: entryCopy.reviewReturnBodyStart,
  },
};

export const FocusDashboardWidget = () => {
  const router = useRouter();
  const searchParams = useSearchParams();
  const { plan, isPro, setPlan } = usePlanTier();
  const { sceneAssetMap } = useMediaCatalog();
  const { summary: weeklySummary } = useFocusStats();

  const reviewEntryPreset = searchParams.get('entryPreset');
  const reviewEntryPresetConfig = useMemo(() => {
    if (!reviewEntryPreset) {
      return null;
    }

    return REVIEW_ENTRY_PRESETS[reviewEntryPreset as keyof typeof REVIEW_ENTRY_PRESETS] ?? null;
  }, [reviewEntryPreset]);
  const initialAtmosphere = useMemo(() => {
    return (
      findAtmosphereOptionForSelection(
        reviewEntryPresetConfig?.sceneId ?? DEFAULT_SCENE_ID,
        reviewEntryPresetConfig?.soundPresetId ?? DEFAULT_SOUND_ID,
      ) ?? DEFAULT_ATMOSPHERE
    );
  }, [reviewEntryPresetConfig]);
  const initialDurationMinutes = useMemo(() => {
    if (reviewEntryPresetConfig) {
      return getTimerPresetMetaById(reviewEntryPresetConfig.timerPresetId).focusMinutes;
    }

    return getRecommendedDurationMinutes(initialAtmosphere);
  }, [initialAtmosphere, reviewEntryPresetConfig]);

  const [goalDraft, setGoalDraft] = useState('');
  const [durationDraft, setDurationDraft] = useState(() => String(initialDurationMinutes));
  const [selectedAtmosphereId, setSelectedAtmosphereId] = useState(initialAtmosphere.id);
  const [hasEditedDuration, setHasEditedDuration] = useState(false);
  const [isStartingSession, setIsStartingSession] = useState(false);
  const [paywallSource, setPaywallSource] = useState<string | null>(null);
  const [currentSession, setCurrentSession] = useState<FocusSession | null>(null);
  const [isCheckingSession, setIsCheckingSession] = useState(true);
  const [sessionLookupError, setSessionLookupError] = useState<string | null>(null);

  const goalInputRef = useRef<HTMLInputElement | null>(null);
  const selectedAtmosphere = useMemo(
    () => getAtmosphereOptionById(selectedAtmosphereId),
    [selectedAtmosphereId],
  );
  const rawDurationValue = useMemo(() => {
    const digitsOnly = durationDraft.replace(/[^\d]/g, '');
    if (!digitsOnly) {
      return null;
    }

    const parsed = Number(digitsOnly);
    return Number.isFinite(parsed) ? parsed : null;
  }, [durationDraft]);
  const parsedDurationMinutes = parseDurationMinutes(durationDraft);
  const resolvedTimerPreset = useMemo(() => {
    const targetMinutes =
      parsedDurationMinutes ?? getRecommendedDurationMinutes(selectedAtmosphere);
    return resolveNearestTimerPreset(targetMinutes);
  }, [parsedDurationMinutes, selectedAtmosphere]);

  const activeScene = useMemo(() => {
    return getSceneById(currentSession?.sceneId ?? selectedAtmosphere.sceneId) ?? SCENE_THEMES[0];
  }, [currentSession?.sceneId, selectedAtmosphere.sceneId]);

  const trimmedGoal = goalDraft.trim();
  const canStart =
    trimmedGoal.length > 0 &&
    parsedDurationMinutes !== null &&
    !isStartingSession &&
    !currentSession;
  const hasEnoughWeeklyData =
    weeklySummary.last7Days.startedSessions >= 3 &&
    (weeklySummary.last7Days.completedSessions >= 2 ||
      weeklySummary.recovery.pausedSessions > 0);
  const reviewSource = searchParams.get('review');
  const reviewCarryHint = searchParams.get('carryHint');
  const normalizedReviewCarryHint: ReviewCarryHint | null =
    reviewCarryHint === 'steady' ||
    reviewCarryHint === 'smaller' ||
    reviewCarryHint === 'closure' ||
    reviewCarryHint === 'start'
      ? reviewCarryHint
      : null;
  const isReviewReturn =
    reviewSource === 'weekly' && normalizedReviewCarryHint !== null;
  const reviewReturnCopy =
    normalizedReviewCarryHint !== null ? reviewCarryCopyByHint[normalizedReviewCarryHint] : null;
  const reviewReturnRitualLabel =
    isPro && reviewEntryPresetConfig ? `추천 ritual · ${reviewEntryPresetConfig.label}` : null;
  const reviewTeaserTitle = isPro ? entryCopy.reviewTitlePro : entryCopy.reviewTitle;
  const durationHelper =
    rawDurationValue !== null && rawDurationValue < 5
      ? 'Please enter at least 5 minutes.'
      : parsedDurationMinutes === null
        ? 'Please enter the estimated duration in minutes.'
        : entryCopy.durationHelper;
  const hasCurrentSession = Boolean(currentSession);

  useEffect(() => {
    let cancelled = false;

    const loadCurrentSession = async () => {
      setIsCheckingSession(true);

      try {
        const session = await focusSessionApi.getCurrentSession();
        if (cancelled) {
          return;
        }
        setCurrentSession(session);
        setSessionLookupError(null);
      } catch (error) {
        if (cancelled) {
          return;
        }
        setCurrentSession(null);
        setSessionLookupError(error instanceof Error ? error.message : entryCopy.loadFailed);
      } finally {
        if (!cancelled) {
          setIsCheckingSession(false);
        }
      }
    };

    void loadCurrentSession();

    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    if (!isCheckingSession && hasCurrentSession) {
      router.replace('/space');
    }
  }, [hasCurrentSession, isCheckingSession, router]);

  const openPaywall = () => {
    if (!isPro) {
      setPaywallSource('app-entry-plan-pill');
    }
  };

  const handleDurationChange = (value: string) => {
    setDurationDraft(sanitizeDurationDraft(value));
    setHasEditedDuration(true);
  };

  const handleSelectDuration = (minutes: number) => {
    setDurationDraft(String(minutes));
    setHasEditedDuration(true);
  };

  const handleSelectAtmosphere = (atmosphereId: string) => {
    const nextAtmosphere = getAtmosphereOptionById(atmosphereId);
    setSelectedAtmosphereId(nextAtmosphere.id);

    if (!hasEditedDuration) {
      setDurationDraft(String(getRecommendedDurationMinutes(nextAtmosphere)));
    }
  };

  const handleStartSession = async () => {
    if (!trimmedGoal || isStartingSession || currentSession) {
      if (!trimmedGoal) {
        goalInputRef.current?.focus();
      }
      return;
    }

    if (parsedDurationMinutes === null) {
      return;
    }

    setIsStartingSession(true);

    try {
      await focusSessionApi.startSession({
        goal: trimmedGoal,
        microStep: null,
        sceneId: selectedAtmosphere.sceneId,
        soundPresetId: selectedAtmosphere.soundPresetId,
        timerPresetId: resolvedTimerPreset.id,
        entryPoint: 'space-setup',
      });
      router.push('/space');
      return;
    } catch (error) {
      const message =
        error instanceof Error ? error.message : entryCopy.loadFailed;
      setSessionLookupError(message);

      try {
        const session = await focusSessionApi.getCurrentSession();
        if (session) {
          setCurrentSession(session);
        }
      } catch (syncError) {
        console.error('Failed to sync current session after /app start failure', syncError);
      }

      console.error('Failed to start focus session from /app', error);
    }

    setIsStartingSession(false);
  };

  const shouldShowWeeklyReviewTeaser =
    !isCheckingSession && !currentSession && hasEnoughWeeklyData && !isReviewReturn;

  return (
    <div className="relative min-h-dvh bg-black text-white selection:bg-white/20">
      {/* Background Media */}
      <div
        className={cn(
          'fixed inset-0 bg-cover bg-center transition-transform duration-[1.5s] ease-[cubic-bezier(0.22,1,0.36,1)]',
          isStartingSession ? 'scale-[1.08] blur-[2px] brightness-75' : 'scale-100 blur-[60px] brightness-50',
        )}
        style={getSceneStageBackgroundStyle(activeScene, sceneAssetMap?.[activeScene.id])}
      />
      {/* Immersive Overlay Gradients */}
      <div className="fixed inset-0 bg-[radial-gradient(circle_at_center,transparent_0%,rgba(0,0,0,0.85)_100%)] mix-blend-multiply pointer-events-none" />
      <div className="fixed inset-0 bg-black/40 pointer-events-none" />

      {/* Header */}
      <header className="absolute top-0 inset-x-0 z-50 flex items-center justify-between px-8 py-8 md:px-12 md:py-10">
        <div className="flex items-center gap-3 opacity-0 animate-fade-in delay-150">
          <p className="text-[11px] font-bold uppercase tracking-[0.4em] text-white/50 drop-shadow-sm">
            {entryCopy.eyebrow}
          </p>
          {plan === 'pro' && (
            <span className="rounded-full bg-white/10 px-2 py-0.5 text-[9px] font-bold uppercase tracking-widest text-white/60 backdrop-blur-md">
              PRO
            </span>
          )}
        </div>
        {plan !== 'pro' && (
          <button
            type="button"
            onClick={openPaywall}
            className="group flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-4 py-1.5 text-[10px] font-semibold uppercase tracking-widest text-white/50 backdrop-blur-md transition-all hover:bg-white/10 hover:text-white/80 opacity-0 animate-fade-in delay-150"
          >
            <span>Upgrade</span>
            <span className="transition-transform group-hover:translate-x-0.5">&rarr;</span>
          </button>
        )}
      </header>

      {/* Main Content Area */}
      <main className="relative z-10 flex min-h-[100dvh] flex-col pb-8 pt-20 md:pt-24">
        {isCheckingSession ? (
          <div className="flex flex-1 items-center justify-center">
            <p className="text-[15px] font-medium text-white/70 animate-pulse">Loading session...</p>
          </div>
        ) : (
          <div className="flex-1 flex flex-col w-full relative">
            <AppAtmosphereEntryShell
              canStart={canStart}
              durationDraft={durationDraft}
              durationHelper={durationHelper}
              durationInputLabel={entryCopy.durationLabel}
              durationPlaceholder={entryCopy.durationPlaceholder}
              durationSuggestions={ENTRY_DURATION_SUGGESTIONS}
              goalDraft={goalDraft}
              goalInputRef={goalInputRef}
              goalPlaceholder={entryCopy.goalPlaceholder}
              isStartingSession={isStartingSession}
              topAccessory={
                reviewReturnCopy ? (
                  <div className="flex flex-col items-center text-center">
                    <div className="mb-3 inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-3 py-1.5 text-[10px] font-bold uppercase tracking-[0.2em] text-white/60 backdrop-blur-md">
                      <span className="h-1.5 w-1.5 rounded-full bg-white/40" />
                      {entryCopy.reviewReturnEyebrow}
                    </div>
                    <p className="text-lg font-medium tracking-tight text-white/90">
                      {reviewReturnCopy.title}
                    </p>
                    <p className="mt-1.5 max-w-md text-[13px] leading-relaxed text-white/50">
                      {reviewReturnCopy.body}
                    </p>
                    {reviewReturnRitualLabel && (
                      <p className="mt-3 text-[11px] font-medium text-white/40">
                        {reviewReturnRitualLabel}
                      </p>
                    )}
                  </div>
                ) : shouldShowWeeklyReviewTeaser ? (
                  <Link href="/stats" className="group inline-flex items-center gap-3 rounded-full border border-white/5 bg-white/5 py-2 pl-4 pr-3 backdrop-blur-md transition-all hover:bg-white/10 hover:border-white/10">
                    <span className="flex h-1.5 w-1.5 rounded-full bg-white/40 group-hover:bg-white/60 transition-colors" />
                    <span className="text-[13px] font-medium text-white/70 group-hover:text-white/90">
                      {reviewTeaserTitle}
                    </span>
                    <span className="text-white/40 transition-transform group-hover:translate-x-0.5">&rarr;</span>
                  </Link>
                ) : undefined
              }
              errorAccessory={
                sessionLookupError ? (
                  <div className="inline-flex items-center gap-2 rounded-full border border-red-500/20 bg-red-500/10 px-4 py-2 text-sm text-red-200 backdrop-blur-md">
                    <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                    </svg>
                    {sessionLookupError}
                  </div>
                ) : undefined
              }
              selectedAtmosphere={selectedAtmosphere}
              startButtonLabel={entryCopy.startNow}
              startButtonLoadingLabel={entryCopy.startLoading}
              atmosphereOptions={ATMOSPHERE_OPTIONS}
              atmosphereTitle={entryCopy.atmosphereTitle}
              atmosphereBody={entryCopy.atmosphereBody}
              onDurationChange={handleDurationChange}
              onGoalChange={setGoalDraft}
              onSelectAtmosphere={handleSelectAtmosphere}
              onSelectDuration={handleSelectDuration}
              onStartSession={() => {
                void handleStartSession();
              }}
            />
          </div>
        )}
      </main>

      {/* Paywall Overlay */}
      {paywallSource && (
        <div className="fixed inset-0 z-[100] flex items-end justify-center p-4 sm:items-center">
          <button
            type="button"
            aria-label={copy.modal.closeAriaLabel}
            onClick={() => setPaywallSource(null)}
            className="absolute inset-0 bg-black/60 backdrop-blur-sm transition-opacity"
          />
          <div className="relative z-10 w-full max-w-md rounded-[2rem] border border-white/10 bg-zinc-900/90 p-6 shadow-2xl backdrop-blur-xl">
            <p className="mb-2 text-[11px] font-medium uppercase tracking-[0.2em] text-white/50">
              {entryCopy.paywallLead}
            </p>
            <p className="mb-6 text-sm leading-relaxed text-white/80">{entryCopy.paywallBody}</p>
            <PaywallSheetContent
              onStartPro={() => {
                setPlan('pro');
                setPaywallSource(null);
              }}
              onClose={() => setPaywallSource(null)}
            />
          </div>
        </div>
      )}
    </div>
  );
};
