'use client';

import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useEffect, useMemo, useRef, useState } from 'react';
import {
  type FocusPlanItem,
  type FocusPlanToday,
  useFocusPlan,
} from '@/entities/focus-plan';
import { usePlanTier } from '@/entities/plan';
import { SCENE_THEMES, getSceneById } from '@/entities/scene';
import { useMediaCatalog, getSceneStageBackgroundStyle } from '@/entities/media';
import { SOUND_PRESETS } from '@/entities/session';
import { PaywallSheetContent } from '@/features/paywall-sheet';
import { PlanPill } from '@/features/plan-pill';
import { useFocusStats } from '@/features/stats';
import { focusSessionApi } from '@/features/focus-session/api/focusSessionApi';
import { copy } from '@/shared/i18n';
import { cn } from '@/shared/lib/cn';
import { useDragScroll } from '@/shared/lib/useDragScroll';
import { FocusPlanManageSheet, type FocusPlanEditingState } from './FocusPlanManageSheet';

const FREE_MAX_ITEMS = 1;
const PRO_MAX_ITEMS = 5;

const focusEntryCopy = {
  eyebrow: 'VibeRoom',
  title: '오늘의 깊은 몰입을 위한 단 하나의 목표',
  description: '지금 당장 시작할 딱 하나만 남겨두세요.',
  inputLabel: '첫 블록',
  inputPlaceholder: '예: 제안서 첫 문단만 다듬기',
  helper: '아주 작게 잡아도 괜찮아요.',
  startNow: '바로 몰입하기',
  nextStep: '환경 세팅',
  manageBlocks: '내 계획에서 가져오기',
  previewTitle: '이어갈 블록',
  previewDescription: '다음 후보는 가볍게만 두고, 시작은 위 버튼 하나로 끝냅니다.',
  reviewLinkLabel: 'stats',
  reviewFallback: '최근 7일 흐름을 불러오는 중이에요.',
  ritualMeta: '기본 설정으로 들어갑니다. 공간 안에서 언제든 바꿀 수 있어요.',
  apiUnavailableNote: '계획 연결이 잠시 느려요. 지금은 첫 블록부터 바로 시작할 수 있어요.',
  freeUpgradeLabel: '두 번째 블록부터는 PRO',
  paywallSource: 'focus-entry-manage-sheet',
  paywallLead: 'Calm Session OS PRO',
  paywallBody: '여러 블록을 이어서 정리하는 manage sheet는 PRO에서 열립니다.',
  microStepTitle: '가장 작은 첫 단계 (선택)',
  microStepHelper: '이 목표를 위해 당장 할 수 있는 5분짜리 행동은 무엇인가요?',
  microStepPlaceholder: '예: 폴더 열기, 노션 켜기',
  ritualTitle: '어떤 환경에서 몰입하시겠어요?',
  ritualHelper: '오늘의 무드를 선택하세요.',
};

const ENTRY_SUGGESTIONS = [
  { id: 'tidy-10m', label: '정리 10분', goal: '정리 10분만 하기' },
  { id: 'mail-3', label: '메일 3개', goal: '메일 3개 정리' },
  { id: 'doc-1p', label: '문서 1p', goal: '문서 1p 다듬기' },
] as const;

type EntrySource = 'starter' | 'plan' | 'custom';
type DashboardStep = 'goal' | 'ritual';

const getVisiblePlanItems = (
  currentItem: FocusPlanItem | null,
  nextItems: FocusPlanItem[],
  limit: number,
) => {
  return [currentItem, ...nextItems]
    .filter((item): item is FocusPlanItem => Boolean(item))
    .slice(0, limit);
};

const resolveVisiblePlanItems = (nextPlan: FocusPlanToday | null, limit: number) => {
  return getVisiblePlanItems(nextPlan?.currentItem ?? null, nextPlan?.nextItems ?? [], limit);
};

// Premium Glassmorphism UI Classes
const glassInputClass = 'w-full rounded-full border border-white/20 bg-black/20 px-8 py-5 text-center text-lg md:text-xl font-light tracking-wide text-white placeholder:text-white/40 shadow-2xl backdrop-blur-xl outline-none transition-all focus:border-white/40 focus:bg-black/30 focus:ring-4 focus:ring-white/10';
const primaryGlassBtnClass = 'inline-flex items-center justify-center rounded-full border border-white/20 bg-white/20 px-8 py-4 text-base font-medium text-white shadow-xl backdrop-blur-xl transition-all hover:bg-white/30 hover:scale-[1.02] active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed';
const secondaryGlassBtnClass = 'inline-flex items-center justify-center rounded-full border border-white/10 bg-transparent px-8 py-4 text-base font-medium text-white/80 transition-all hover:bg-white/10 hover:text-white active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed';
const panelGlassClass = 'rounded-[2rem] border border-white/10 bg-black/40 p-6 md:p-8 shadow-2xl backdrop-blur-2xl';
const itemCardGlassClass = 'relative flex flex-col items-center justify-center overflow-hidden rounded-2xl border border-white/10 bg-white/5 p-4 text-white transition-all hover:bg-white/10 active:scale-95 cursor-pointer';
const itemCardGlassSelectedClass = 'border-white/40 bg-white/20 shadow-[0_0_20px_rgba(255,255,255,0.1)]';

export const FocusDashboardWidget = () => {
  const router = useRouter();
  const { plan: planTier, isPro, setPlan } = usePlanTier();
  const { plan, isLoading, isSaving, error, source, createItem, updateItem, deleteItem } = useFocusPlan();
  const { sceneAssetMap } = useMediaCatalog();

  const [step, setStep] = useState<DashboardStep>('goal');
  const [paywallSource, setPaywallSource] = useState<string | null>(null);
  const [manageSheetOpen, setManageSheetOpen] = useState(false);
  const [editingState, setEditingState] = useState<FocusPlanEditingState>(null);
  
  const [entryDraft, setEntryDraft] = useState('');
  const [selectedPlanItemId, setSelectedPlanItemId] = useState<string | null>(null);
  const [entrySource, setEntrySource] = useState<EntrySource>('starter');
  
  const [microStepDraft, setMicroStepDraft] = useState('');
  // Use user's last preference or default to first
  const [selectedSceneId, setSelectedSceneId] = useState(SCENE_THEMES[0].id);
  const [selectedSoundId, setSelectedSoundId] = useState(SOUND_PRESETS[0].id);
  const [selectedTimerId, setSelectedTimerId] = useState('50-10');
  
  const [isStartingSession, setIsStartingSession] = useState(false);

  const entryInputRef = useRef<HTMLInputElement | null>(null);
  const microStepInputRef = useRef<HTMLInputElement | null>(null);
  const inputRef = useRef<HTMLInputElement | null>(null);

  const {
    containerRef: sceneContainerRef,
    events: sceneDragEvents,
    isDragging: isSceneDragging,
    shouldSuppressClick: shouldSuppressSceneClick,
  } = useDragScroll();

  const selectedScene = useMemo(() => getSceneById(selectedSceneId) ?? SCENE_THEMES[0], [selectedSceneId]);

  const maxItems = isPro ? PRO_MAX_ITEMS : FREE_MAX_ITEMS;
  const planItems = useMemo(() => {
    return getVisiblePlanItems(plan.currentItem, plan.nextItems, maxItems);
  }, [maxItems, plan.currentItem, plan.nextItems]);

  const currentItem = planItems[0] ?? null;
  
  const hasPendingEdit = editingState !== null;
  const canAddMore = planItems.length < maxItems;
  const canManagePlan = source === 'api' && !isLoading;
  const trimmedEntryGoal = entryDraft.trim();
  const isGoalReady = trimmedEntryGoal.length > 0;

  useEffect(() => {
    if (!editingState) return;
    const rafId = window.requestAnimationFrame(() => {
      inputRef.current?.focus();
      inputRef.current?.select();
    });
    return () => window.cancelAnimationFrame(rafId);
  }, [editingState]);

  useEffect(() => {
    if (!currentItem) return;
    if (entrySource === 'starter' || (entrySource === 'plan' && !selectedPlanItemId)) {
      setEntryDraft(currentItem.title);
      setSelectedPlanItemId(currentItem.id);
      setEntrySource('plan');
    }
  }, [currentItem, entryDraft, entrySource, selectedPlanItemId]);

  const openPaywall = () => setPaywallSource(focusEntryCopy.paywallSource);

  const handleSelectPlanItem = (item: FocusPlanItem) => {
    const isCurrentSelection = currentItem?.id === item.id;
    setEntryDraft(item.title);
    setSelectedPlanItemId(isCurrentSelection ? item.id : null);
    setEntrySource(isCurrentSelection ? 'plan' : 'custom');
    setManageSheetOpen(false);
  };

  const handleSelectSuggestion = (goal: string) => {
    setEntryDraft(goal);
    setSelectedPlanItemId(null);
    setEntrySource('starter');
  };

  const handleEntryDraftChange = (value: string) => {
    setEntryDraft(value);
    setEntrySource('custom');
    setSelectedPlanItemId(null);
  };

  const handleAddBlock = () => {
    if (hasPendingEdit || isSaving || !canManagePlan) return;
    if (!canAddMore) {
      if (!isPro) openPaywall();
      return;
    }
    setEditingState({ mode: 'new', value: '' });
  };

  const handleEditRow = (item: FocusPlanItem) => {
    if (hasPendingEdit || isSaving) return;
    setEditingState({ mode: 'edit', itemId: item.id, value: item.title });
  };

  const handleManageDraftChange = (value: string) => {
    setEditingState((current) => current ? { ...current, value } : current);
  };

  const handleCancelEdit = () => {
    if (!isSaving) setEditingState(null);
  };

  const handleSaveEdit = async () => {
    if (!editingState) return;
    const trimmedTitle = editingState.value.trim();
    if (!trimmedTitle) return;

    if (editingState.mode === 'new') {
      const nextPlan = await createItem({ title: trimmedTitle });
      if (!nextPlan) return;
      setEditingState(null);
      if (!currentItem) {
        const nextVisiblePlanItems = resolveVisiblePlanItems(nextPlan, maxItems);
        const nextCurrentItem = nextVisiblePlanItems[0] ?? null;
        if (nextCurrentItem) {
          setEntryDraft(nextCurrentItem.title);
          setSelectedPlanItemId(nextCurrentItem.id);
          setEntrySource('plan');
        }
      }
      return;
    }

    const currentRow = planItems.find((item) => item.id === editingState.itemId);
    if (!currentRow) return;
    if (currentRow.title === trimmedTitle) {
      setEditingState(null);
      return;
    }

    const nextPlan = await updateItem(editingState.itemId, { title: trimmedTitle });
    if (!nextPlan) return;
    setEditingState(null);
    if (selectedPlanItemId === editingState.itemId) {
      setEntryDraft(trimmedTitle);
      setEntrySource('plan');
    }
  };

  const handleDeleteRow = async (itemId: string) => {
    const nextPlan = await deleteItem(itemId);
    if (!nextPlan) return;
    if (editingState?.mode === 'edit' && editingState.itemId === itemId) {
      setEditingState(null);
    }
    if (selectedPlanItemId === itemId) {
      const nextVisiblePlanItems = resolveVisiblePlanItems(nextPlan, maxItems);
      const nextCurrentItem = nextVisiblePlanItems[0] ?? null;
      if (nextCurrentItem) {
        setEntryDraft(nextCurrentItem.title);
        setSelectedPlanItemId(nextCurrentItem.id);
        setEntrySource('plan');
        return;
      }
      setEntryDraft('');
      setSelectedPlanItemId(null);
      setEntrySource('custom');
    }
  };

  const handleNextStep = () => {
    if (!isGoalReady) {
      entryInputRef.current?.focus();
      return;
    }
    if (step === 'goal') setStep('ritual');
  };

  const handleStartSession = async () => {
    if (isStartingSession) return;
    setIsStartingSession(true);

    try {
      await focusSessionApi.startSession({
        goal: trimmedEntryGoal,
        microStep: microStepDraft.trim() || null,
        sceneId: selectedSceneId,
        soundPresetId: selectedSoundId,
        timerPresetId: selectedTimerId,
        focusPlanItemId: selectedPlanItemId || undefined,
        entryPoint: 'space-setup'
      });
      router.push('/space');
    } catch (err) {
      console.error('Failed to start session', err);
      setIsStartingSession(false);
    }
  };

  return (
    <div className="relative min-h-dvh overflow-hidden bg-slate-900 text-white font-sans selection:bg-white/20">
      {/* Premium Cinematic Background */}
      <div
        className={cn(
          "absolute inset-0 bg-cover bg-center transition-all duration-1000 ease-out will-change-transform",
          isStartingSession ? 'scale-110 blur-2xl opacity-0' : 'scale-100 opacity-100',
          step === 'ritual' ? 'scale-105 blur-sm' : ''
        )}
        style={getSceneStageBackgroundStyle(selectedScene, sceneAssetMap?.[selectedScene.id])}
      />
      {/* Global Gradient Overlay for text readability */}
      <div className={cn(
        "absolute inset-0 bg-gradient-to-b from-black/20 via-black/40 to-black/60 transition-opacity duration-1000",
        step === 'ritual' ? 'opacity-80' : 'opacity-100'
      )} />

      {/* Header */}
      <header className="absolute top-0 left-0 right-0 z-20 flex items-center justify-between p-6 md:p-8">
        <p className="text-sm font-semibold tracking-[0.3em] text-white/50 uppercase">
          {focusEntryCopy.eyebrow}
        </p>
        <PlanPill
          plan={planTier}
          onClick={() => {
            if (!isPro) openPaywall();
          }}
        />
      </header>

      {/* Main Content Area */}
      <main className="relative z-10 flex h-dvh flex-col items-center justify-center px-4">
        
        {/* Step 1: Goal Setup */}
        <div className={cn(
          "w-full max-w-2xl transition-all duration-700 absolute",
          step === 'goal' 
            ? 'opacity-100 translate-y-0 pointer-events-auto' 
            : 'opacity-0 -translate-y-8 pointer-events-none'
        )}>
          <div className="flex flex-col items-center space-y-10 text-center">
            <h1 className="text-3xl md:text-5xl font-light tracking-tight text-white drop-shadow-lg leading-tight">
              {focusEntryCopy.title}
            </h1>
            
            <div className="w-full max-w-xl mx-auto space-y-8">
              <input
                ref={entryInputRef}
                value={entryDraft}
                onChange={(event) => handleEntryDraftChange(event.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && handleNextStep()}
                placeholder={focusEntryCopy.inputPlaceholder}
                className={glassInputClass}
                autoFocus
              />

              <div className="flex flex-col sm:flex-row items-center justify-center gap-4">
                <button
                  type="button"
                  onClick={handleStartSession}
                  disabled={!isGoalReady || isStartingSession}
                  className={primaryGlassBtnClass}
                >
                  {focusEntryCopy.startNow}
                </button>
                <button
                  type="button"
                  onClick={handleNextStep}
                  disabled={!isGoalReady || isStartingSession}
                  className={secondaryGlassBtnClass}
                >
                  {focusEntryCopy.nextStep}
                </button>
              </div>

              {/* Suggestions / Manage - very minimal */}
              <div className="pt-8 flex flex-col items-center gap-4 opacity-70 hover:opacity-100 transition-opacity">
                <div className="flex flex-wrap justify-center gap-2">
                  {ENTRY_SUGGESTIONS.map((suggestion) => {
                    const isActive = selectedPlanItemId === null && trimmedEntryGoal === suggestion.goal;
                    return (
                      <button
                        key={suggestion.id}
                        type="button"
                        onClick={() => handleSelectSuggestion(suggestion.goal)}
                        className={cn(
                          'rounded-full px-4 py-1.5 text-sm transition-all border',
                          isActive
                            ? 'bg-white/20 border-white text-white'
                            : 'bg-transparent border-white/20 text-white/70 hover:border-white/40 hover:text-white'
                        )}
                      >
                        {suggestion.label}
                      </button>
                    );
                  })}
                </div>
                <button
                  type="button"
                  onClick={() => setManageSheetOpen(true)}
                  disabled={!canManagePlan}
                  className="text-sm font-medium text-white/50 hover:text-white transition-colors underline underline-offset-4 decoration-white/20"
                >
                  {focusEntryCopy.manageBlocks}
                </button>
              </div>
            </div>
          </div>
        </div>

        {/* Step 2: Ritual Setup */}
        <div className={cn(
          "w-full max-w-4xl transition-all duration-700 absolute",
          step === 'ritual' 
            ? 'opacity-100 translate-y-0 pointer-events-auto' 
            : 'opacity-0 translate-y-8 pointer-events-none'
        )}>
          <div className={panelGlassClass}>
            <div className="flex items-center justify-between mb-8 pb-6 border-b border-white/10">
              <div className="flex-1">
                <p className="text-xs uppercase tracking-widest text-white/40 mb-2">Today's Focus</p>
                <p className="text-xl md:text-2xl font-light text-white truncate pr-4">{trimmedEntryGoal}</p>
              </div>
              <button
                type="button"
                onClick={() => setStep('goal')}
                className="rounded-full border border-white/20 bg-white/5 px-4 py-2 text-sm text-white hover:bg-white/10 transition-colors"
              >
                수정
              </button>
            </div>

            <div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-12">
              <div className="space-y-8">
                {/* Microstep */}
                <div className="space-y-3">
                  <label className="block space-y-2">
                    <span className="text-sm font-medium text-white/80">
                      {focusEntryCopy.microStepTitle}
                    </span>
                    <input
                      ref={microStepInputRef}
                      value={microStepDraft}
                      onChange={(e) => setMicroStepDraft(e.target.value)}
                      onKeyDown={(e) => e.key === 'Enter' && handleStartSession()}
                      placeholder={focusEntryCopy.microStepPlaceholder}
                      className="w-full rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-white placeholder:text-white/30 outline-none transition-all focus:border-white/30 focus:bg-white/10"
                    />
                  </label>
                  <p className="text-xs text-white/40">{focusEntryCopy.microStepHelper}</p>
                </div>

                {/* Timer */}
                <div className="space-y-3">
                  <p className="text-sm font-medium text-white/80">몰입 리듬</p>
                  <div className="grid grid-cols-3 gap-2">
                    {[{id: '25-5', label: '25 / 5'}, {id: '50-10', label: '50 / 10'}, {id: '90-20', label: '90 / 20'}].map(timer => (
                      <button
                        key={timer.id}
                        type="button"
                        onClick={() => setSelectedTimerId(timer.id)}
                        className={cn(itemCardGlassClass, selectedTimerId === timer.id && itemCardGlassSelectedClass)}
                      >
                        <span className="text-sm font-medium">{timer.label}</span>
                      </button>
                    ))}
                  </div>
                </div>
              </div>

              <div className="space-y-8">
                {/* Scene */}
                <div className="space-y-3">
                  <p className="text-sm font-medium text-white/80">배경 공간</p>
                  <div 
                    ref={sceneContainerRef}
                    {...sceneDragEvents}
                    className={cn(
                      "flex gap-3 overflow-x-auto pb-2 scrollbar-none",
                      isSceneDragging ? "cursor-grabbing" : "cursor-grab"
                    )}
                  >
                    {SCENE_THEMES.map(scene => (
                      <button
                        key={scene.id}
                        type="button"
                        onClick={() => {
                          if (!shouldSuppressSceneClick) {
                            setSelectedSceneId(scene.id);
                          }
                        }}
                        className={cn(
                          'group relative h-24 min-w-[120px] rounded-xl border border-white/10 text-left transition-all overflow-hidden bg-white/5 active:scale-95',
                          selectedSceneId === scene.id && 'border-white/40 shadow-[0_0_20px_rgba(255,255,255,0.1)]',
                          isSceneDragging && 'pointer-events-none'
                        )}
                        style={getSceneStageBackgroundStyle(scene, sceneAssetMap?.[scene.id])}
                      >
                        <div className="absolute inset-0 bg-black/40 transition-opacity group-hover:bg-black/20" />
                        <span className="absolute bottom-2 left-2 text-sm font-medium z-10 text-white text-shadow-sm">{scene.name}</span>
                        {selectedSceneId === scene.id && (
                          <span className="absolute top-2 right-2 z-20 flex h-5 w-5 items-center justify-center rounded-full bg-white/20 backdrop-blur-sm border border-white/40 text-white text-[10px]">
                            ✓
                          </span>
                        )}
                      </button>
                    ))}
                  </div>
                </div>

                {/* Sound */}
                <div className="space-y-3">
                  <p className="text-sm font-medium text-white/80">사운드</p>
                  <div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
                    {SOUND_PRESETS.map(sound => (
                      <button
                        key={sound.id}
                        type="button"
                        onClick={() => setSelectedSoundId(sound.id)}
                        className={cn(itemCardGlassClass, "py-3", selectedSoundId === sound.id && itemCardGlassSelectedClass)}
                      >
                        <span className="text-sm font-medium">{sound.label}</span>
                      </button>
                    ))}
                  </div>
                </div>
              </div>
            </div>

            <div className="mt-10 pt-6 flex justify-end border-t border-white/10">
              <button
                type="button"
                onClick={handleStartSession}
                disabled={isStartingSession}
                className={primaryGlassBtnClass}
              >
                {isStartingSession ? '공간으로 이동 중...' : '입장하기'}
              </button>
            </div>
          </div>
        </div>
      </main>

      {/* Plan Sheet & Paywall */}
      <FocusPlanManageSheet
        isOpen={manageSheetOpen}
        planItems={planItems}
        selectedPlanItemId={selectedPlanItemId}
        editingState={editingState}
        isSaving={isSaving}
        canAddMore={canAddMore}
        isPro={isPro}
        inputRef={inputRef}
        onClose={() => {
          if (!isSaving) {
            setManageSheetOpen(false);
            setEditingState(null);
          }
        }}
        onAddBlock={handleAddBlock}
        onDraftChange={handleManageDraftChange}
        onSelect={handleSelectPlanItem}
        onEdit={handleEditRow}
        onDelete={(itemId) => {
          void handleDeleteRow(itemId);
        }}
        onSave={() => {
          void handleSaveEdit();
        }}
        onCancel={handleCancelEdit}
      />

      {paywallSource ? (
        <div className="fixed inset-0 z-50 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-slate-950/48 backdrop-blur-[2px]"
          />
          <div className="relative z-10 w-full max-w-md rounded-3xl border border-white/12 bg-[linear-gradient(165deg,rgba(15,23,42,0.94)_0%,rgba(2,6,23,0.98)_100%)] p-5 shadow-[0_24px_60px_rgba(2,6,23,0.36)]">
            <p className="mb-3 text-[11px] uppercase tracking-[0.16em] text-white/42">
              {focusEntryCopy.paywallLead}
            </p>
            <p className="mb-4 text-sm text-white/62">
              {focusEntryCopy.paywallBody}
            </p>
            <PaywallSheetContent
              onStartPro={() => {
                setPlan('pro');
                setPaywallSource(null);
              }}
              onClose={() => setPaywallSource(null)}
            />
          </div>
        </div>
      ) : null}
    </div>
  );
};
