"use client";

import { useState, useCallback, useEffect, useRef } from "react";
import { cn } from "@/lib/utils";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Search, ChevronRight } from "lucide-react";
import { usePopEvent } from "@/hooks/pop";
import type {
  PopSearchConfig,
  DatePresetOption,
} from "./types";
import { DATE_PRESET_LABELS, computeDateRange } from "./types";

// ========================================
// 메인 컴포넌트
// ========================================

interface PopSearchComponentProps {
  config: PopSearchConfig;
  label?: string;
  screenId?: string;
}

const DEFAULT_CONFIG: PopSearchConfig = {
  inputType: "text",
  fieldName: "",
  placeholder: "검색어 입력",
  debounceMs: 500,
  triggerOnEnter: true,
  labelPosition: "top",
  labelText: "",
  labelVisible: true,
};

export function PopSearchComponent({
  config: rawConfig,
  label,
  screenId,
}: PopSearchComponentProps) {
  const config = { ...DEFAULT_CONFIG, ...(rawConfig || {}) };
  const { publish, setSharedData } = usePopEvent(screenId || "");
  const [value, setValue] = useState<unknown>(config.defaultValue ?? "");

  const emitFilterChanged = useCallback(
    (newValue: unknown) => {
      if (!config.fieldName) return;
      setValue(newValue);
      setSharedData(`search_${config.fieldName}`, newValue);
      publish("filter_changed", { [config.fieldName]: newValue });
    },
    [config.fieldName, publish, setSharedData]
  );

  const showLabel = config.labelVisible !== false && !!config.labelText;

  return (
    <div
      className={cn(
        "flex h-full w-full overflow-hidden",
        showLabel && config.labelPosition === "left"
          ? "flex-row items-center gap-2 p-1.5"
          : "flex-col justify-center gap-0.5 p-1.5"
      )}
    >
      {showLabel && (
        <span className="shrink-0 truncate text-[10px] font-medium text-muted-foreground">
          {config.labelText}
        </span>
      )}
      <div className="min-w-0">
        <SearchInputRenderer
          config={config}
          value={value}
          onChange={emitFilterChanged}
        />
      </div>
    </div>
  );
}

// ========================================
// 서브타입 분기 렌더러
// ========================================

interface InputRendererProps {
  config: PopSearchConfig;
  value: unknown;
  onChange: (v: unknown) => void;
}

function SearchInputRenderer({ config, value, onChange }: InputRendererProps) {
  switch (config.inputType) {
    case "text":
      return (
        <TextSearchInput
          config={config}
          value={String(value ?? "")}
          onChange={onChange}
        />
      );
    case "select":
      return (
        <SelectSearchInput
          config={config}
          value={String(value ?? "")}
          onChange={onChange}
        />
      );
    case "date-preset":
      return <DatePresetSearchInput config={config} value={value} onChange={onChange} />;
    case "toggle":
      return (
        <ToggleSearchInput value={Boolean(value)} onChange={onChange} />
      );
    case "modal-table":
    case "modal-card":
    case "modal-icon-grid":
      return (
        <ModalSearchInput
          config={config}
          value={String(value ?? "")}
        />
      );
    default:
      return <PlaceholderInput inputType={config.inputType} />;
  }
}

// ========================================
// text 서브타입: 디바운스 + Enter
// ========================================

interface TextInputProps {
  config: PopSearchConfig;
  value: string;
  onChange: (v: unknown) => void;
}

function TextSearchInput({ config, value, onChange }: TextInputProps) {
  const [inputValue, setInputValue] = useState(value);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  useEffect(() => {
    setInputValue(value);
  }, [value]);

  useEffect(() => {
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, []);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const v = e.target.value;
    setInputValue(v);

    if (debounceRef.current) clearTimeout(debounceRef.current);
    const ms = config.debounceMs ?? 500;
    if (ms > 0) {
      debounceRef.current = setTimeout(() => onChange(v), ms);
    }
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "Enter" && config.triggerOnEnter !== false) {
      if (debounceRef.current) clearTimeout(debounceRef.current);
      onChange(inputValue);
    }
  };

  return (
    <div className="relative">
      <Search className="absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
      <Input
        value={inputValue}
        onChange={handleChange}
        onKeyDown={handleKeyDown}
        placeholder={config.placeholder || "검색어 입력"}
        className="h-8 pl-7 text-xs"
      />
    </div>
  );
}

// ========================================
// select 서브타입: 즉시 발행
// ========================================

interface SelectInputProps {
  config: PopSearchConfig;
  value: string;
  onChange: (v: unknown) => void;
}

function SelectSearchInput({ config, value, onChange }: SelectInputProps) {
  return (
    <Select
      value={value || undefined}
      onValueChange={(v) => onChange(v)}
    >
      <SelectTrigger className="h-8 text-xs">
        <SelectValue placeholder={config.placeholder || "선택"} />
      </SelectTrigger>
      <SelectContent>
        {(config.options || []).map((opt) => (
          <SelectItem key={opt.value} value={opt.value} className="text-xs">
            {opt.label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}

// ========================================
// date-preset 서브타입: 탭 버튼 + 즉시 발행
// ========================================

interface DatePresetInputProps {
  config: PopSearchConfig;
  value: unknown;
  onChange: (v: unknown) => void;
}

function DatePresetSearchInput({ config, value, onChange }: DatePresetInputProps) {
  const presets: DatePresetOption[] =
    config.datePresets || ["today", "this-week", "this-month"];

  const currentPreset =
    value && typeof value === "object" && "preset" in (value as Record<string, unknown>)
      ? (value as Record<string, unknown>).preset
      : value;

  const handleSelect = (preset: DatePresetOption) => {
    if (preset === "custom") {
      onChange({ preset: "custom", from: "", to: "" });
      return;
    }
    const range = computeDateRange(preset);
    if (range) onChange(range);
  };

  return (
    <div className="flex flex-wrap gap-1">
      {presets.map((preset) => (
        <Button
          key={preset}
          variant={currentPreset === preset ? "default" : "outline"}
          size="sm"
          className="h-7 px-2 text-[10px]"
          onClick={() => handleSelect(preset)}
        >
          {DATE_PRESET_LABELS[preset]}
        </Button>
      ))}
    </div>
  );
}

// ========================================
// toggle 서브타입: Switch + 즉시 발행
// ========================================

interface ToggleInputProps {
  value: boolean;
  onChange: (v: unknown) => void;
}

function ToggleSearchInput({ value, onChange }: ToggleInputProps) {
  return (
    <div className="flex items-center gap-2">
      <Switch
        checked={value}
        onCheckedChange={(checked) => onChange(checked)}
      />
      <span className="text-xs text-muted-foreground">
        {value ? "ON" : "OFF"}
      </span>
    </div>
  );
}

// ========================================
// modal-* 서브타입: readonly 입력 + 아이콘 (MVP: UI만)
// ========================================

interface ModalInputProps {
  config: PopSearchConfig;
  value: string;
}

function ModalSearchInput({ config, value }: ModalInputProps) {
  return (
    <div
      className="flex h-8 cursor-pointer items-center rounded-md border border-input bg-background px-3 transition-colors hover:bg-accent"
      role="button"
      tabIndex={0}
    >
      <span className="flex-1 truncate text-xs">
        {value || config.placeholder || "선택..."}
      </span>
      <ChevronRight className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
    </div>
  );
}

// ========================================
// 미구현 서브타입 플레이스홀더
// ========================================

function PlaceholderInput({ inputType }: { inputType: string }) {
  return (
    <div className="flex h-8 items-center rounded-md border border-dashed border-muted-foreground/30 px-3">
      <span className="text-[10px] text-muted-foreground">
        {inputType} (후속 구현 예정)
      </span>
    </div>
  );
}
