'use client';

import { useEffect, useState, useCallback, useRef } from 'react';
import { useDashboardStore } from '@/stores/dashboardStore';
import {
  getDashboardList,
  getDashboardCards,
  updateDashboard,
  deleteDashboard,
  insertDashboardCard,
  updateCardPositionsBatch,
} from '@/lib/api/dashMenu';
import { DashboardSidebar } from './DashboardSidebar';
import { DashboardCanvas } from './DashboardCanvas';
import { TemplateLibraryModal } from './TemplateLibraryModal';
import { CardSettingsPanel } from './CardSettingsPanel';
import { ControlMode } from '@/components/control/ControlMode';
// ControlPalette 는 ControlMode 의 IDE LeftRail 안에서만 사용됨 (외부 사이드바 교체 폐기)
import { useControlMode } from '@/components/control/hooks/useControlMode';
import { useMenu } from '@/contexts/MenuContext';
import { toast } from 'sonner';
import '@/styles/dashboard.css';

interface DashboardLayoutProps {
  /** 단일 대시보드 모드: AppLayout 사이드바 메뉴가 대시보드 목록 역할을 하므로
   *  자체 DashboardSidebar 를 숨기고 지정된 dashboardId 만 로드한다. */
  dashboardId?: string;
}

export function DashboardLayout({ dashboardId: singleDashboardId }: DashboardLayoutProps = {}) {
  const {
    dashboards,
    activeDashboardId,
    cards,
    editMode,
    setDashboards,
    setActiveDashboard,
    setCards,
    addCard,
    setEditMode,
    openCreate,
    libOpen,
    openLib,
    closeLib,
  } = useDashboardStore();

  const controlActive = useControlMode((s) => s.active);
  // controlMode 는 ControlMode 내부에서만 참조 (외부 사이드바 분기 폐기)
  const { refreshMenus } = useMenu();
  const isSingleMode = !!singleDashboardId;

  const [settingsCardId, setSettingsCardId] = useState<string | null>(null);
  const [initialized, setInitialized] = useState(false);
  const canvasRef = useRef<HTMLDivElement>(null);

  // 대시보드 목록 로드
  const loadDashboards = useCallback(async () => {
    try {
      const result = await getDashboardList();
      const list: Record<string, any>[] = result?.list ?? [];
      setDashboards(list);

      // 단일 모드에서는 URL 의 dashboardId 를 활성화
      if (isSingleMode && singleDashboardId) {
        setActiveDashboard(singleDashboardId);
      } else if (list.length > 0 && !activeDashboardId) {
        // 멀티 모드에서는 첫 번째 대시보드 자동 선택
        const firstId = list[0].objid ?? list[0].OBJID ?? list[0].dashboard_id ?? list[0].DASHBOARD_ID;
        setActiveDashboard(firstId);
      }
      setInitialized(true);
    } catch (err) {
      console.error('[Dashboard] Load failed:', err);
      setInitialized(true);
    }
  }, [setDashboards, setActiveDashboard, activeDashboardId, isSingleMode, singleDashboardId]);

  useEffect(() => { loadDashboards(); }, []);

  // 단일 모드에서 URL id 가 바뀌면 활성 전환
  useEffect(() => {
    if (isSingleMode && singleDashboardId && singleDashboardId !== activeDashboardId) {
      setActiveDashboard(singleDashboardId);
    }
  }, [isSingleMode, singleDashboardId, activeDashboardId, setActiveDashboard]);

  // 대시보드 전환 시 카드 로드
  // stale guard: 응답 도착 시 이미 다른 대시보드로 전환됐으면 무시 (race 방지)
  const loadCards = useCallback(async (dashId: string) => {
    try {
      const cardList = await getDashboardCards(dashId);
      if (useDashboardStore.getState().activeDashboardId === dashId) {
        const normalized = (cardList ?? []).map((c: Record<string, any>) => ({
          ...c,
          position_x: c.position_x ?? c.POSITION_X,
          position_y: c.position_y ?? c.POSITION_Y,
          width: c.width ?? c.WIDTH,
          height: c.height ?? c.HEIGHT,
          is_collapsed: c.is_collapsed ?? c.IS_COLLAPSED ?? false,
        }));
        setCards(normalized);
      }
    } catch (err) {
      console.error('[Dashboard] Load cards failed:', err);
      if (useDashboardStore.getState().activeDashboardId === dashId) {
        setCards([]);
      }
    }
  }, [setCards]);

  useEffect(() => {
    if (activeDashboardId) {
      loadCards(activeDashboardId);
      setEditMode(false);
    }
  }, [activeDashboardId, loadCards, setEditMode]);

  // 활성 대시보드 정보
  const dashKey = (d: Record<string, any>) =>
    d.objid ?? d.OBJID ?? d.dashboard_id ?? d.DASHBOARD_ID;
  const activeDash = dashboards.find((d) => dashKey(d) === activeDashboardId);
  const dashName = activeDash?.name ?? activeDash?.NAME ?? '대시보드';

  // 대시보드 CRUD — 생성 모달은 AppLayout(전역 헤더) 이 소유. 여기서는 모달만 열어준다.
  const handleAddDashboard = () => openCreate();

  const handleRenameDashboard = async (id: string) => {
    const dash = dashboards.find((d) => dashKey(d) === id);
    if (!dash) return;
    const newName = prompt('새 이름:', dash.name ?? dash.NAME ?? '');
    if (!newName?.trim()) return;
    try {
      await updateDashboard(id, { name: newName.trim() });
      await loadDashboards();
      try { await refreshMenus(); } catch { /* refresh 실패 무시 */ }
      toast.success('이름 변경됨');
    } catch (err) {
      toast.error('이름 변경 실패');
    }
  };

  const handleDeleteDashboard = async (id: string) => {
    if (!isSingleMode && dashboards.length <= 1) {
      toast.warning('마지막 대시보드는 삭제할 수 없습니다');
      return;
    }
    const dash = dashboards.find((d) => dashKey(d) === id);
    if (!confirm(`"${dash?.name ?? dash?.NAME}" 을 삭제합니다.`)) return;
    try {
      await deleteDashboard(id);
      await loadDashboards();
      try { await refreshMenus(); } catch { /* refresh 실패 무시 */ }
      toast.info('대시보드 삭제됨');
    } catch (err) {
      toast.error('삭제 실패');
    }
  };

  const handleSwitchDashboard = (id: string) => {
    if (id === activeDashboardId) return;
    setActiveDashboard(id);
  };

  // 템플릿 추가 (라이브러리 → 카드) — 화면 중앙 배치 + 기존 카드 수만큼 stagger
  // 저장 단위: % (0~100). 캔버스 크기 무관하게 반응형으로 동작.
  const handleSelectTemplate = async (template: Record<string, any>) => {
    if (!activeDashboardId) return;
    const templateId = template.template_id ?? template.TEMPLATE_ID;
    try {
      // 기본 크기: 너비 45%, 높이 50%. stagger: 3% 씩 오프셋 (최대 8장 순환)
      const w = 45;
      const h = 50;
      const stagger = (cards.length % 8) * 3;
      const x = Math.max(2, Math.min(100 - w - 2, Math.round((100 - w) / 2) + stagger));
      const y = Math.max(2, Math.min(100 - h - 2, Math.round((100 - h) / 2) + stagger));

      const result = await insertDashboardCard(activeDashboardId, {
        template_id: templateId,
        position_x: x,
        position_y: y,
        width: w,
        height: h,
      });
      addCard({
        ...result,
        template_id: templateId,
        template_name: template.name ?? template.NAME,
        template_category: template.category ?? template.CATEGORY,
        primary_table: template.primary_table ?? template.PRIMARY_TABLE,
        position_x: x,
        position_y: y,
        width: w,
        height: h,
        is_collapsed: false,
      });
      closeLib();
      if (!editMode) setEditMode(true);
      toast.success(`${template.name ?? template.NAME} 카드를 추가했습니다`);
    } catch (err) {
      toast.error('카드 추가 실패');
    }
  };

  // 레이아웃 저장
  const handleSaveLayout = useCallback(async () => {
    if (!activeDashboardId) return;
    try {
      const cardPositions = cards.map((c) => ({
        card_id: c.card_id ?? c.CARD_ID,
        position_x: c.position_x ?? c.POSITION_X ?? 0,
        position_y: c.position_y ?? c.POSITION_Y ?? 0,
        width: c.width ?? c.WIDTH ?? 600,
        height: c.height ?? c.HEIGHT ?? 400,
        is_collapsed: c.is_collapsed ?? c.IS_COLLAPSED ?? false,
      }));
      await updateCardPositionsBatch(activeDashboardId, cardPositions);
      toast.success(`${cards.length}개 카드 레이아웃 저장됨`);
    } catch (err) {
      toast.error('저장 실패');
    }
  }, [activeDashboardId, cards]);

  // 헤더/FAB 가 dispatchEvent('dash:save') 로 저장 요청 → 여기서 수신해 실행
  useEffect(() => {
    const onSaveReq = () => { handleSaveLayout(); };
    window.addEventListener('dash:save', onSaveReq);
    return () => window.removeEventListener('dash:save', onSaveReq);
  }, [handleSaveLayout]);

  // 설정 카드 정보
  const settingsCard = settingsCardId
    ? cards.find((c) => (c.card_id ?? c.CARD_ID) === settingsCardId)
    : null;

  if (!initialized) {
    return (
      <div className="dash-shell" style={{ alignItems: 'center', justifyContent: 'center' }}>
        <div style={{ color: 'var(--v5-text-muted)', fontSize: '.8rem' }}>로딩 중...</div>
      </div>
    );
  }

  return (
    <div className="dash-shell">
      {/* 사이드바 — 단일 모드에선 AppLayout 메뉴가 대시보드 목록 역할이므로 자체 사이드바 숨김.
          제어 모드 takeover 는 ControlMode 의 IDE LeftRail 이 담당 (v3 V3Takeover) — 외부 사이드바 교체 X */}
      {!isSingleMode && !controlActive ? (
        <DashboardSidebar
          onAddDashboard={handleAddDashboard}
          onRenameDashboard={handleRenameDashboard}
          onDeleteDashboard={handleDeleteDashboard}
          onSwitchDashboard={handleSwitchDashboard}
        />
      ) : null}
      {/* 제어 모드 ON 이지만 카드 미선택 상태에서는 사이드바 자체를 숨김 (IDE 가 화면 takeover 할 자리 확보) */}
      <div className="dash-content">
        {activeDashboardId ? (
          <>
            {/* 편집/제어 툴바는 이제 헤더로 hoist. 캔버스 FAB 이 모드 내 액션 담당. */}
            {/* ★ flex container로 만들어야 안쪽 dash-canvas가 flex:1로 늘어남 */}
            <div style={{ position: 'relative', flex: '1 1 auto', display: 'flex', flexDirection: 'column', minHeight: 0, minWidth: 0, width: '100%', height: '100%' }}>
              <DashboardCanvas
                ref={canvasRef}
                dashboardName={dashName}
                onOpenLibrary={() => openLib()}
                onOpenSettings={(id) => setSettingsCardId(id)}
                controlMode={controlActive}
              />
              <ControlMode
                dashboardId={activeDashboardId}
                cards={cards}
                canvasRef={canvasRef}
              />
              {settingsCard && !controlActive && (
                <CardSettingsPanel
                  cardId={settingsCardId!}
                  tableName={settingsCard.primary_table ?? settingsCard.PRIMARY_TABLE ?? ''}
                  onClose={() => setSettingsCardId(null)}
                />
              )}
            </div>
          </>
        ) : (
          <div style={{
            flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center',
            flexDirection: 'column', gap: '.8rem',
          }}>
            <div style={{ fontSize: '3rem', opacity: .25 }}>📋</div>
            <div style={{ fontSize: '.9rem', fontWeight: 700, color: 'var(--v5-text-sec)' }}>
              대시보드가 없습니다
            </div>
            <button className="dash-empty-btn" onClick={handleAddDashboard}>
              + 새 대시보드 만들기
            </button>
          </div>
        )}
      </div>

      <TemplateLibraryModal
        open={libOpen}
        onClose={() => closeLib()}
        onSelectTemplate={handleSelectTemplate}
      />
    </div>
  );
}
