"use client";

/**
 * DynamicConfigPanel
 * 
 * JSON Schema 기반으로 동적으로 설정 UI를 생성하는 패널
 * 모든 V2 컴포넌트의 설정을 단일 컴포넌트로 처리
 */

import React, { useCallback, useMemo } from "react";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Slider } from "@/components/ui/slider";
import { Textarea } from "@/components/ui/textarea";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import { ChevronDown } from "lucide-react";
import { JSONSchemaProperty, V2ConfigSchema } from "@/types/v2-components";
import { cn } from "@/lib/utils";

interface DynamicConfigPanelProps {
  schema: V2ConfigSchema;
  config: Record<string, unknown>;
  onChange: (key: string, value: unknown) => void;
  className?: string;
}

/**
 * 개별 스키마 속성을 렌더링하는 컴포넌트
 */
function SchemaField({
  name,
  property,
  value,
  onChange,
  path = [],
}: {
  name: string;
  property: JSONSchemaProperty;
  value: unknown;
  onChange: (key: string, value: unknown) => void;
  path?: string[];
}) {
  const fieldPath = [...path, name].join(".");
  
  // 값 변경 핸들러
  const handleChange = useCallback(
    (newValue: unknown) => {
      onChange(fieldPath, newValue);
    },
    [fieldPath, onChange]
  );

  // 타입에 따른 컴포넌트 렌더링
  const renderField = () => {
    // enum이 있으면 Select 렌더링
    if (property.enum && property.enum.length > 0) {
      return (
        <Select
          value={String(value ?? property.default ?? "")}
          onValueChange={handleChange}
        >
          <SelectTrigger className="h-8 text-xs">
            <SelectValue placeholder="선택" />
          </SelectTrigger>
          <SelectContent>
            {property.enum.map((option) => (
              <SelectItem key={option} value={option} className="text-xs">
                {option}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      );
    }

    // 타입별 렌더링
    switch (property.type) {
      case "string":
        return (
          <Input
            type="text"
            value={String(value ?? property.default ?? "")}
            onChange={(e) => handleChange(e.target.value)}
            placeholder={property.description}
            className="h-8 text-xs"
          />
        );

      case "number":
        return (
          <Input
            type="number"
            value={value !== undefined && value !== null ? Number(value) : ""}
            onChange={(e) => handleChange(e.target.value ? Number(e.target.value) : undefined)}
            placeholder={property.description}
            className="h-8 text-xs"
          />
        );

      case "boolean":
        return (
          <Switch
            checked={Boolean(value ?? property.default ?? false)}
            onCheckedChange={handleChange}
          />
        );

      case "array":
        // 배열은 간단한 텍스트 입력으로 처리 (쉼표 구분)
        return (
          <Textarea
            value={Array.isArray(value) ? value.join(", ") : ""}
            onChange={(e) => {
              const arr = e.target.value.split(",").map((s) => s.trim()).filter(Boolean);
              handleChange(arr);
            }}
            placeholder="쉼표로 구분하여 입력"
            className="text-xs min-h-[60px]"
          />
        );

      case "object":
        // 중첩 객체는 별도 섹션으로 렌더링
        if (property.properties) {
          return (
            <div className="mt-2 pl-4 border-l-2 border-muted space-y-3">
              {Object.entries(property.properties).map(([subName, subProp]) => (
                <SchemaField
                  key={subName}
                  name={subName}
                  property={subProp}
                  value={(value as Record<string, unknown>)?.[subName]}
                  onChange={onChange}
                  path={[...path, name]}
                />
              ))}
            </div>
          );
        }
        return null;

      default:
        return (
          <Input
            type="text"
            value={String(value ?? "")}
            onChange={(e) => handleChange(e.target.value)}
            className="h-8 text-xs"
          />
        );
    }
  };

  return (
    <div className="space-y-1.5">
      <div className="flex items-center justify-between">
        <Label className="text-xs font-medium">
          {property.title || name}
        </Label>
        {property.type === "boolean" && renderField()}
      </div>
      {property.description && (
        <p className="text-[10px] text-muted-foreground">{property.description}</p>
      )}
      {property.type !== "boolean" && renderField()}
    </div>
  );
}

/**
 * 메인 DynamicConfigPanel 컴포넌트
 */
export function DynamicConfigPanel({
  schema,
  config,
  onChange,
  className,
}: DynamicConfigPanelProps) {
  // 속성들을 카테고리별로 그룹화
  const groupedProperties = useMemo(() => {
    const groups: Record<string, Array<[string, JSONSchemaProperty]>> = {
      기본: [],
      고급: [],
      스타일: [],
    };

    Object.entries(schema.properties).forEach(([name, property]) => {
      // 이름 기반으로 그룹 분류
      if (name.includes("style") || name.includes("Style")) {
        groups["스타일"].push([name, property]);
      } else if (
        name.includes("cascade") ||
        name.includes("mutual") ||
        name.includes("conditional") ||
        name.includes("autoFill")
      ) {
        groups["고급"].push([name, property]);
      } else {
        groups["기본"].push([name, property]);
      }
    });

    return groups;
  }, [schema.properties]);

  // 값 변경 핸들러 (중첩 경로 지원)
  const handleChange = useCallback(
    (path: string, value: unknown) => {
      onChange(path, value);
    },
    [onChange]
  );

  return (
    <div className={cn("space-y-4", className)}>
      {Object.entries(groupedProperties).map(
        ([groupName, properties]) =>
          properties.length > 0 && (
            <Collapsible key={groupName} defaultOpen={groupName === "기본"}>
              <Card>
                <CollapsibleTrigger asChild>
                  <CardHeader className="cursor-pointer py-3 px-4">
                    <CardTitle className="text-sm font-medium flex items-center justify-between">
                      {groupName} 설정
                      <ChevronDown className="h-4 w-4" />
                    </CardTitle>
                  </CardHeader>
                </CollapsibleTrigger>
                <CollapsibleContent>
                  <CardContent className="pt-0 space-y-4">
                    {properties.map(([name, property]) => (
                      <SchemaField
                        key={name}
                        name={name}
                        property={property}
                        value={config[name]}
                        onChange={handleChange}
                      />
                    ))}
                  </CardContent>
                </CollapsibleContent>
              </Card>
            </Collapsible>
          )
      )}
    </div>
  );
}

/**
 * 기본 스키마들 (자주 사용되는 설정)
 */
export const COMMON_SCHEMAS = {
  // V2Input 기본 스키마
  V2Input: {
    type: "object" as const,
    properties: {
      type: {
        type: "string" as const,
        enum: ["text", "number", "password", "slider", "color", "button"],
        default: "text",
        title: "입력 타입",
      },
      format: {
        type: "string" as const,
        enum: ["none", "email", "tel", "url", "currency", "biz_no"],
        default: "none",
        title: "형식",
      },
      placeholder: {
        type: "string" as const,
        title: "플레이스홀더",
      },
      min: {
        type: "number" as const,
        title: "최소값",
        description: "숫자 타입 전용",
      },
      max: {
        type: "number" as const,
        title: "최대값",
        description: "숫자 타입 전용",
      },
      step: {
        type: "number" as const,
        title: "증가 단위",
      },
    },
  },

  // V2Select 기본 스키마
  V2Select: {
    type: "object" as const,
    properties: {
      mode: {
        type: "string" as const,
        enum: ["dropdown", "radio", "check", "tag", "toggle", "swap"],
        default: "dropdown",
        title: "표시 모드",
      },
      source: {
        type: "string" as const,
        enum: ["static", "code", "db", "api", "entity"],
        default: "static",
        title: "데이터 소스",
      },
      codeGroup: {
        type: "string" as const,
        title: "코드 그룹",
        description: "source가 code일 때 사용",
      },
      searchable: {
        type: "boolean" as const,
        default: false,
        title: "검색 가능",
      },
      multiple: {
        type: "boolean" as const,
        default: false,
        title: "다중 선택",
      },
      maxSelect: {
        type: "number" as const,
        title: "최대 선택 수",
      },
      cascading: {
        type: "object" as const,
        title: "연쇄 관계",
        properties: {
          parentField: { type: "string" as const, title: "부모 필드" },
          filterColumn: { type: "string" as const, title: "필터 컬럼" },
          clearOnChange: { type: "boolean" as const, default: true, title: "부모 변경시 초기화" },
        },
      },
    },
  },

  // V2Date 기본 스키마
  V2Date: {
    type: "object" as const,
    properties: {
      type: {
        type: "string" as const,
        enum: ["date", "time", "datetime"],
        default: "date",
        title: "타입",
      },
      format: {
        type: "string" as const,
        default: "YYYY-MM-DD",
        title: "날짜 형식",
      },
      range: {
        type: "boolean" as const,
        default: false,
        title: "범위 선택",
      },
      showToday: {
        type: "boolean" as const,
        default: true,
        title: "오늘 버튼",
      },
    },
  },
} satisfies Record<string, V2ConfigSchema>;

export default DynamicConfigPanel;


