"use client";

import { useState } from "react";
import type { Block, ButtonBlockProps, FormBlockProps, ListBlockProps, SectionBlockProps, TextBlockProps, VideoBlockProps } from "@/features/editor/state/editorStore";
import { ButtonPropertiesPanel } from "./ButtonPropertiesPanel";
import { TextPropertiesPanel } from "./TextPropertiesPanel";
import { ListPropertiesPanel } from "./ListPropertiesPanel";
import { DividerPropertiesPanel } from "./DividerPropertiesPanel";
import { ImagePropertiesPanel } from "./ImagePropertiesPanel";
import { SectionPropertiesPanel } from "./SectionPropertiesPanel";
import { VideoPropertiesPanel } from "./VideoPropertiesPanel";
import { FormInputPropertiesPanel } from "../forms/FormInputPropertiesPanel";
import { FormSelectPropertiesPanel } from "../forms/FormSelectPropertiesPanel";
import { FormCheckboxPropertiesPanel } from "../forms/FormCheckboxPropertiesPanel";
import { FormRadioPropertiesPanel } from "../forms/FormRadioPropertiesPanel";
import { FormControllerPanel } from "../forms/FormControllerPanel";
import { ProjectPropertiesPanel } from "./ProjectPropertiesPanel";
import { Trash2, Copy, SlidersHorizontal, HelpCircle } from "lucide-react";
import { useAppLocale } from "@/features/i18n/LocaleProvider";
import { getEditorPropertiesSidebarMessages } from "@/features/i18n/messages/editorPropertiesSidebar";

type BlockHelpProperty = {
  label: string;
  description: string;
};

type BlockHelpContent = {
  title: string;
  description: string;
  properties?: BlockHelpProperty[];
};

interface PropertiesSidebarProps {
  blocks: Block[];
  selectedBlockId: string | null;
  selectedListItemId: string | null;
  updateBlock: (id: string, partial: any) => void;
  removeBlock: (id: string) => void;
  duplicateBlock: (id: string) => void;
  // 텍스트 속성 패널에서 사용하는 인라인 편집 상태를 그대로 전달한다.
  editingBlockId: string | null;
  setEditingText: (value: string) => void;
  onMoveSelectedItemUp: (blockId: string) => void;
  onMoveSelectedItemDown: (blockId: string) => void;
  onIndentSelectedItem: (blockId: string) => void;
  onOutdentSelectedItem: (blockId: string) => void;
}

// 우측 속성 패널을 분리한 컴포넌트
export function PropertiesSidebar(props: PropertiesSidebarProps) {
  const {
    blocks,
    selectedBlockId,
    selectedListItemId,
    updateBlock,
    removeBlock,
    duplicateBlock,
    editingBlockId,
    setEditingText,
    onMoveSelectedItemUp,
    onMoveSelectedItemDown,
    onIndentSelectedItem,
    onOutdentSelectedItem,
  } = props;

  const [helpOpen, setHelpOpen] = useState(false);
  const locale = useAppLocale();
  const m = getEditorPropertiesSidebarMessages(locale);

  const getHelpContentForSelectedBlock = (): BlockHelpContent | null => {
    if (!selectedBlockId) return null;
    const selectedBlock = blocks.find((b) => b.id === selectedBlockId);
    if (!selectedBlock) return null;

    switch (selectedBlock.type) {
      case "text":
        return m.text;
      case "button":
        return m.button;
      case "image":
        return m.image;
      case "list":
        return m.list;
      case "divider":
        return m.divider;
      case "section":
        return m.section;
      case "video":
        return m.video;
      case "form":
        return m.form;
      case "formInput":
        return m.formInput;
      case "formSelect":
        return m.formSelect;
      case "formCheckbox":
        return m.formCheckbox;
      case "formRadio":
        return m.formRadio;
      default:
        return m.fallback;
    }
  };

  return (
    <aside
      data-testid="properties-sidebar"
      className="w-80 p-4 text-sm border-l border-slate-200 bg-white flex flex-col gap-4 overflow-auto pb-scroll dark:border-slate-800 dark:bg-slate-950/40"
      onKeyDownCapture={(e) => {
        // 속성 패널 안에서 발생한 키 입력은 에디터 단축키/텍스트 블록 편집으로 전달되지 않도록 막는다.
        e.stopPropagation();
      }}
    >
      <h2 className="font-medium mb-2 flex items-center gap-2 text-slate-900 dark:text-slate-100">
        <SlidersHorizontal className="w-4 h-4 text-sky-400" aria-hidden="true" />
        <span>{m.panelTitle}</span>
      </h2>
      {selectedBlockId ? (
        <div className="space-y-3">
          <div className="flex gap-2 text-[11px]">
            <button
              type="button"
              className="flex-1 rounded border border-slate-200 bg-slate-50 px-2 py-1 text-slate-900 hover:bg-red-50 hover:border-red-300 hover:text-red-700 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100 dark:hover:bg-red-900/60 dark:hover:border-red-700"
              onClick={() => removeBlock(selectedBlockId)}
            >
              <span className="inline-flex items-center gap-2">
                <Trash2 className="w-3 h-3" aria-hidden="true" />
                <span>{m.actionDeleteBlock}</span>
              </span>
            </button>
            <button
              type="button"
              className="flex-1 rounded border border-slate-200 bg-slate-50 px-2 py-1 text-slate-900 hover:bg-slate-100 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100 dark:hover:bg-slate-800"
              onClick={() => duplicateBlock(selectedBlockId)}
            >
              <span className="inline-flex items-center gap-2">
                <Copy className="w-3 h-3" aria-hidden="true" />
                <span>{m.actionDuplicateBlock}</span>
              </span>
            </button>
          </div>
          <div className="flex justify-end text-[11px]">
            <button
              type="button"
              className="inline-flex items-center gap-1 rounded border border-slate-200 bg-slate-50 px-2 py-1 text-slate-900 hover:bg-slate-100 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100 dark:hover:bg-slate-800"
              onClick={() => setHelpOpen(true)}
            >
              <HelpCircle className="w-3 h-3" aria-hidden="true" />
              <span>{m.actionHelp}</span>
            </button>
          </div>
          {(() => {
            const selectedBlock = blocks.find((b) => b.id === selectedBlockId);
            if (!selectedBlock) return null;

            if (selectedBlock.type === "text") {
              const textProps = selectedBlock.props as TextBlockProps;

              return (
                <TextPropertiesPanel
                  textProps={textProps}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                  editingBlockId={editingBlockId}
                  setEditingText={setEditingText}
                />
              );
            }

            if (selectedBlock.type === "button") {
              const buttonProps = selectedBlock.props as ButtonBlockProps;

              return (
                <ButtonPropertiesPanel
                  buttonProps={buttonProps}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            if (selectedBlock.type === "list") {
              const listProps = selectedBlock.props as ListBlockProps;

              return (
                <ListPropertiesPanel
                  listProps={listProps}
                  selectedBlockId={selectedBlockId}
                  selectedListItemId={selectedListItemId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            if (selectedBlock.type === "divider") {
              const dividerProps = selectedBlock.props as any;

              return (
                <DividerPropertiesPanel
                  dividerProps={dividerProps}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            if (selectedBlock.type === "image") {
              const imageProps = selectedBlock.props as any;

              return (
                <ImagePropertiesPanel
                  imageProps={imageProps}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            if (selectedBlock.type === "video") {
              const videoProps = selectedBlock.props as VideoBlockProps;

              return (
                <VideoPropertiesPanel
                  videoProps={videoProps}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            if (selectedBlock.type === "section") {
              const sectionProps = selectedBlock.props as SectionBlockProps;

              return (
                <SectionPropertiesPanel
                  sectionProps={sectionProps}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            if (selectedBlock.type === "formInput") {
              return (
                <FormInputPropertiesPanel
                  block={selectedBlock}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            if (selectedBlock.type === "formSelect") {
              return (
                <FormSelectPropertiesPanel
                  block={selectedBlock}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            if (selectedBlock.type === "formCheckbox") {
              return (
                <FormCheckboxPropertiesPanel
                  block={selectedBlock}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            if (selectedBlock.type === "formRadio") {
              return (
                <FormRadioPropertiesPanel
                  block={selectedBlock}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            if (selectedBlock.type === "form") {
              return (
                <FormControllerPanel
                  block={selectedBlock}
                  blocks={blocks}
                  selectedBlockId={selectedBlockId}
                  updateBlock={(id, partial) => updateBlock(id, partial as any)}
                />
              );
            }

            return null;
          })()}
        </div>
      ) : (
        <ProjectPropertiesPanel />
      )}
      {helpOpen && (() => {
        const help = getHelpContentForSelectedBlock();
        if (!help) return null;

        return (
          <div className="fixed inset-0 z-40 flex items-center justify-center bg-black/60">
            <div className="w-full max-w-md rounded-lg border border-slate-200 bg-white p-4 text-xs text-slate-900 shadow-xl dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100">
              <div className="flex items-center justify-between mb-2">
                <h3 className="text-sm font-medium">{help.title}</h3>
                <button
                  type="button"
                  className="text-slate-600 dark:text-slate-400 hover:text-slate-100 text-xs"
                  onClick={() => setHelpOpen(false)}
                >
                  {m.modalCloseLabel}
                </button>
              </div>
              <p className="text-[11px] text-slate-600 dark:text-slate-200 whitespace-pre-line">{help.description}</p>
              {help.properties && help.properties.length > 0 && (
                <div className="mt-3 border-t border-slate-700 pt-2 space-y-2">
                  <h4 className="text-[11px] font-semibold text-slate-900 dark:text-slate-200">{m.modalPropertiesSectionTitle}</h4>
                  <ul className="space-y-1">
                    {help.properties.map((prop) => (
                      <li key={prop.label}>
                        <div className="text-[11px] font-semibold text-slate-600 dark:text-slate:-100">{prop.label}</div>
                        <div className="text-[11px] text-slate-500 dark:text-slate-300">{prop.description}</div>
                      </li>
                    ))}
                  </ul>
                </div>
              )}
            </div>
          </div>
        );
      })()}
    </aside>
  );
}
