"use client";

import React, { useMemo } from "react";
import { cn } from "@/lib/utils";
import { NumberingRuleConfig, NumberingRulePart, CodePartType } from "@/types/numbering-rule";
import { CODE_PART_TYPE_OPTIONS } from "@/types/numbering-rule";

/** 파트별 표시값 + 타입 (미리보기 스트립/세그먼트용) */
export interface PartDisplayItem {
  partType: CodePartType;
  displayValue: string;
  order: number;
}

/** config에서 파트별 표시값 배열 계산 (정렬된 parts 기준) */
export function computePartDisplayItems(config: NumberingRuleConfig): PartDisplayItem[] {
  if (!config.parts || config.parts.length === 0) return [];
  const sorted = [...config.parts].sort((a, b) => a.order - b.order);
  const globalSep = config.separator ?? "-";
  return sorted.map((part) => ({
    order: part.order,
    partType: part.partType,
    displayValue: getPartDisplayValue(part),
  }));
}

function getPartDisplayValue(part: NumberingRulePart): string {
  if (part.generationMethod === "manual") {
    return part.manualConfig?.value || "XXX";
  }
  const c = part.autoConfig || {};
  switch (part.partType) {
    case "sequence":
      return String(c.startFrom ?? 1).padStart(c.sequenceLength ?? 3, "0");
    case "number":
      return String(c.numberValue ?? 0).padStart(c.numberLength ?? 4, "0");
    case "date": {
      const format = c.dateFormat || "YYYYMMDD";
      if (c.useColumnValue && c.sourceColumnName) {
        return format === "YYYY" ? "[YYYY]" : format === "YY" ? "[YY]" : format === "YYYYMM" ? "[YYYYMM]" : format === "YYMM" ? "[YYMM]" : format === "YYMMDD" ? "[YYMMDD]" : "[DATE]";
      }
      const now = new Date();
      const y = now.getFullYear();
      const m = String(now.getMonth() + 1).padStart(2, "0");
      const d = String(now.getDate()).padStart(2, "0");
      if (format === "YYYY") return String(y);
      if (format === "YY") return String(y).slice(-2);
      if (format === "YYYYMM") return `${y}${m}`;
      if (format === "YYMM") return `${String(y).slice(-2)}${m}`;
      if (format === "YYYYMMDD") return `${y}${m}${d}`;
      if (format === "YYMMDD") return `${String(y).slice(-2)}${m}${d}`;
      return `${y}${m}${d}`;
    }
    case "text":
      return c.textValue || "TEXT";
    default:
      return "XXX";
  }
}

/** 파트 타입별 미리보기용 텍스트 색상 클래스 (CSS 변수 기반) */
export function getPartTypeColorClass(partType: CodePartType): string {
  switch (partType) {
    case "date":
      return "text-warning";
    case "text":
      return "text-primary";
    case "sequence":
      return "text-primary";
    case "number":
      return "text-muted-foreground";
    case "category":
    case "reference":
      return "text-muted-foreground";
    default:
      return "text-foreground";
  }
}

/** 파트 타입별 점(dot) 배경 색상 (범례용) */
export function getPartTypeDotClass(partType: CodePartType): string {
  switch (partType) {
    case "date":
      return "bg-warning";
    case "text":
    case "sequence":
      return "bg-primary";
    case "number":
    case "category":
    case "reference":
      return "bg-muted-foreground";
    default:
      return "bg-foreground";
  }
}

interface NumberingRulePreviewProps {
  config: NumberingRuleConfig;
  compact?: boolean;
  /** 큰 미리보기 스트립: 28px, 파트별 색상, 하단 범례 */
  variant?: "default" | "strip";
}

export const NumberingRulePreview: React.FC<NumberingRulePreviewProps> = ({ 
  config, 
  compact = false,
  variant = "default",
}) => {
  const partItems = useMemo(() => computePartDisplayItems(config), [config]);
  const sortedParts = useMemo(
    () => (config.parts ? [...config.parts].sort((a, b) => a.order - b.order) : []),
    [config.parts]
  );
  const generatedCode = useMemo(() => {
    if (partItems.length === 0) return "규칙을 추가해주세요";
    const globalSep = config.separator ?? "-";
    let result = "";
    partItems.forEach((item, idx) => {
      result += item.displayValue;
      if (idx < partItems.length - 1) {
        const part = sortedParts.find((p) => p.order === item.order);
        result += part?.separatorAfter ?? globalSep;
      }
    });
    return result;
  }, [config.separator, partItems, sortedParts]);

  if (variant === "strip") {
    const globalSep = config.separator ?? "-";
    return (
      <div className="rounded-lg border border-border bg-gradient-to-b from-muted to-card px-4 py-4 sm:px-6 sm:py-5">
        <div className="font-mono text-[22px] font-extrabold tracking-tight sm:text-[28px]">
          {partItems.length === 0 ? (
            <span className="text-muted-foreground">규칙을 추가해주세요</span>
          ) : (
            partItems.map((item, idx) => (
              <React.Fragment key={item.order}>
                <span className={getPartTypeColorClass(item.partType)}>{item.displayValue}</span>
                {idx < partItems.length - 1 && (
                  <span className="text-muted-foreground">
                    {sortedParts.find((p) => p.order === item.order)?.separatorAfter ?? globalSep}
                  </span>
                )}
              </React.Fragment>
            ))
          )}
        </div>
        {partItems.length > 0 && (
          <div className="preview-desc mt-3 flex flex-wrap gap-x-4 gap-y-1 text-xs text-muted-foreground">
            {CODE_PART_TYPE_OPTIONS.filter((opt) => partItems.some((p) => p.partType === opt.value)).map((opt) => (
              <span key={opt.value} className="flex items-center gap-1.5">
                <span className={cn("h-[6px] w-[6px] shrink-0 rounded-full", getPartTypeDotClass(opt.value))} />
                {opt.label}
              </span>
            ))}
          </div>
        )}
      </div>
    );
  }

  if (compact) {
    return (
      <div className="rounded-md bg-muted px-2 py-1">
        <code className="text-xs font-mono text-foreground">{generatedCode}</code>
      </div>
    );
  }

  return (
    <div className="rounded-md bg-muted px-3 py-2">
      <code className="text-sm font-mono text-foreground">{generatedCode}</code>
    </div>
  );
};
