"use client";

import type { CardRendererProps, QueryResult } from "./types";
import type {
  CardLayoutConfig,
  CardLayoutRow,
  CardElement,
  CardHeaderElement,
  CardDataCellElement,
  CardDividerElement,
  CardBadgeElement,
  CardImageElement,
  CardNumberElement,
  CardDateElement,
  CardLinkElement,
  CardStatusElement,
  CardSpacerElement,
  CardStaticTextElement,
} from "@/types/report";
import * as LucideIcons from "lucide-react";

// ─────────────────────────────────────────────────────────────────────────────
// 기존 cardItems 방식 렌더러 (하위 호환)
// ─────────────────────────────────────────────────────────────────────────────
function CardListRenderer({ component, getQueryResult }: CardRendererProps) {
  const cardTitle = component.cardTitle || "정보 카드";
  const cardItems = component.cardItems || [];
  const labelWidth = component.labelWidth || 80;
  const showCardTitle = component.showCardTitle !== false;
  const titleFontSize = component.titleFontSize || 14;
  const labelFontSize = component.labelFontSize || 13;
  const valueFontSize = component.valueFontSize || 13;
  const titleColor = component.titleColor || "#1e40af";
  const labelColor = component.labelColor || "#374151";
  const valueColor = component.valueColor || "#000000";

  const getCardItemValue = (item: {
    label: string;
    value: string;
    fieldName?: string;
  }) => {
    if (item.fieldName && component.queryId) {
      const queryResult = getQueryResult(component.queryId);
      if (queryResult && queryResult.rows && queryResult.rows.length > 0) {
        const row = queryResult.rows[0];
        return row[item.fieldName] !== undefined
          ? String(row[item.fieldName])
          : item.value;
      }
    }
    return item.value;
  };

  return (
    <div className="flex h-full w-full flex-col overflow-hidden">
      {showCardTitle && (
        <>
          <div
            className="flex-shrink-0 px-2 py-1 font-semibold"
            style={{ fontSize: `${titleFontSize}px`, color: titleColor }}
          >
            {cardTitle}
          </div>
          <div
            className="mx-1 flex-shrink-0 border-b"
            style={{ borderColor: component.borderColor || "#e5e7eb" }}
          />
        </>
      )}
      <div className="flex-1 overflow-auto px-2 py-1">
        {cardItems.map(
          (
            item: { label: string; value: string; fieldName?: string },
            index: number,
          ) => (
            <div key={index} className="flex py-0.5">
              <span
                className="flex-shrink-0 font-medium"
                style={{
                  width: `${labelWidth}px`,
                  fontSize: `${labelFontSize}px`,
                  color: labelColor,
                }}
              >
                {item.label}
              </span>
              <span
                className="flex-1"
                style={{ fontSize: `${valueFontSize}px`, color: valueColor }}
              >
                {getCardItemValue(item)}
              </span>
            </div>
          ),
        )}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// v3 요소별 렌더러
// ─────────────────────────────────────────────────────────────────────────────

interface ElementRendererProps {
  element: CardElement;
  getQueryResult: (queryId: string) => QueryResult | null;
  queryId?: string;
  config: CardLayoutConfig;
}

function CardHeaderRenderer({
  element,
  config,
}: {
  element: CardHeaderElement;
  config: CardLayoutConfig;
}) {
  const titleFontSize =
    element.titleFontSize || config.headerTitleFontSize || 14;
  const titleColor = element.titleColor || config.headerTitleColor || "#1e40af";
  const iconColor = element.iconColor || titleColor;

  const IconComponent = element.icon
    ? (LucideIcons as Record<string, React.ComponentType<{ className?: string; style?: React.CSSProperties }>>)[element.icon]
    : null;

  return (
    <div
      className="flex items-center gap-2 py-1"
      style={{ gridColumn: `span ${element.colspan || 1}` }}
    >
      {IconComponent && (
        <IconComponent
          className="w-4 h-4 flex-shrink-0"
          style={{ color: iconColor }}
        />
      )}
      <span
        className="font-semibold"
        style={{ fontSize: `${titleFontSize}px`, color: titleColor }}
      >
        {element.title}
      </span>
    </div>
  );
}

function CardDataCellRenderer({
  element,
  getQueryResult,
  queryId,
  config,
}: {
  element: CardDataCellElement;
  getQueryResult: (queryId: string) => QueryResult | null;
  queryId?: string;
  config: CardLayoutConfig;
}) {
  const labelFontSize =
    element.labelFontSize || config.labelFontSize || 13;
  const labelColor = element.labelColor || config.labelColor || "#374151";
  const valueFontSize =
    element.valueFontSize || config.valueFontSize || 13;
  const valueColor = element.valueColor || config.valueColor || "#000000";

  const getValue = (): string => {
    if (element.columnName && queryId) {
      const queryResult = getQueryResult(queryId);
      if (queryResult && queryResult.rows && queryResult.rows.length > 0) {
        const row = queryResult.rows[0];
        const value = row[element.columnName];
        return value !== undefined && value !== null ? String(value) : "";
      }
    }
    return "";
  };

  const value = getValue() || "-";

  if (element.direction === "vertical") {
    return (
      <div
        className="flex flex-col py-1"
        style={{ gridColumn: `span ${element.colspan || 1}` }}
      >
        <span
          className="font-medium mb-0.5"
          style={{ fontSize: `${labelFontSize}px`, color: labelColor }}
        >
          {element.label}
        </span>
        <span style={{ fontSize: `${valueFontSize}px`, color: valueColor }}>
          {value}
        </span>
      </div>
    );
  }

  return (
    <div
      className="flex items-center py-1"
      style={{ gridColumn: `span ${element.colspan || 1}` }}
    >
      <span
        className="font-medium flex-shrink-0"
        style={{
          width: element.labelWidth ? `${element.labelWidth}px` : "auto",
          minWidth: "60px",
          fontSize: `${labelFontSize}px`,
          color: labelColor,
        }}
      >
        {element.label}
      </span>
      <span
        className="flex-1"
        style={{ fontSize: `${valueFontSize}px`, color: valueColor }}
      >
        {value}
      </span>
    </div>
  );
}

function CardDividerRenderer({
  element,
  config,
}: {
  element: CardDividerElement;
  config: CardLayoutConfig;
}) {
  const thickness = element.thickness || config.dividerThickness || 1;
  const color = element.color || config.dividerColor || "#e5e7eb";
  const style = element.style || "solid";

  return (
    <div
      className="py-1"
      style={{ gridColumn: `span ${element.colspan || 1}` }}
    >
      <div
        style={{
          borderTopWidth: `${thickness}px`,
          borderTopStyle: style,
          borderTopColor: color,
        }}
      />
    </div>
  );
}

function CardBadgeRenderer({
  element,
  getQueryResult,
  queryId,
}: {
  element: CardBadgeElement;
  getQueryResult: (queryId: string) => QueryResult | null;
  queryId?: string;
  config: CardLayoutConfig;
}) {
  const getValue = (): string => {
    if (element.columnName && queryId) {
      const queryResult = getQueryResult(queryId);
      if (queryResult && queryResult.rows && queryResult.rows.length > 0) {
        const row = queryResult.rows[0];
        const value = row[element.columnName];
        return value !== undefined && value !== null ? String(value) : "";
      }
    }
    return "";
  };

  const value = getValue();
  const bgColor = element.colorMap?.[value] || "#e5e7eb";

  return (
    <div
      className="flex items-center gap-2 py-1"
      style={{ gridColumn: `span ${element.colspan || 1}` }}
    >
      {element.label && (
        <span className="text-sm text-gray-600">{element.label}</span>
      )}
      <span
        className="px-2 py-0.5 rounded text-xs font-medium"
        style={{ backgroundColor: bgColor }}
      >
        {value || "-"}
      </span>
    </div>
  );
}

function getFieldValue(
  columnName: string | undefined,
  queryId: string | undefined,
  getQueryResult: (id: string) => QueryResult | null,
): string {
  if (!columnName || !queryId) return "";
  const result = getQueryResult(queryId);
  if (result?.rows?.length) {
    const val = result.rows[0][columnName];
    return val !== undefined && val !== null ? String(val) : "";
  }
  return "";
}

function formatNumber(raw: string, format?: string, suffix?: string): string {
  const num = parseFloat(raw);
  if (isNaN(num)) return raw || "-";
  if (format === "comma" || format === "currency") {
    const formatted = num.toLocaleString("ko-KR");
    return format === "currency" ? `${formatted}${suffix || "원"}` : formatted;
  }
  return raw;
}

function CardImageRenderer({
  element,
  getQueryResult,
  queryId,
}: {
  element: CardImageElement;
  getQueryResult: (id: string) => QueryResult | null;
  queryId?: string;
}) {
  const url = getFieldValue(element.columnName, queryId, getQueryResult);
  return (
    <div style={{ gridColumn: `span ${element.colspan || 1}`, height: element.height || 80 }}>
      {url ? (
        <img
          src={url}
          alt={element.altText || ""}
          style={{ width: "100%", height: "100%", objectFit: element.objectFit || "contain" }}
        />
      ) : (
        <div className="flex items-center justify-center h-full bg-gray-100 text-xs text-gray-400 rounded">
          이미지
        </div>
      )}
    </div>
  );
}

function CardNumberRenderer({
  element,
  getQueryResult,
  queryId,
  config,
}: {
  element: CardNumberElement;
  getQueryResult: (id: string) => QueryResult | null;
  queryId?: string;
  config: CardLayoutConfig;
}) {
  const raw = getFieldValue(element.columnName, queryId, getQueryResult);
  const value = formatNumber(raw, element.numberFormat, element.currencySuffix);
  const labelFontSize = element.labelFontSize || config.labelFontSize || 13;
  const labelColor = element.labelColor || config.labelColor || "#374151";
  const valueFontSize = element.valueFontSize || config.valueFontSize || 13;
  const valueColor = element.valueColor || config.valueColor || "#000000";

  return (
    <div className="flex flex-col py-1" style={{ gridColumn: `span ${element.colspan || 1}` }}>
      <span className="font-medium mb-0.5" style={{ fontSize: `${labelFontSize}px`, color: labelColor }}>
        {element.label}
      </span>
      <span style={{ fontSize: `${valueFontSize}px`, color: valueColor }}>{value}</span>
    </div>
  );
}

function CardDateRenderer({
  element,
  getQueryResult,
  queryId,
  config,
}: {
  element: CardDateElement;
  getQueryResult: (id: string) => QueryResult | null;
  queryId?: string;
  config: CardLayoutConfig;
}) {
  const raw = getFieldValue(element.columnName, queryId, getQueryResult);
  const labelFontSize = element.labelFontSize || config.labelFontSize || 13;
  const labelColor = element.labelColor || config.labelColor || "#374151";
  const valueFontSize = element.valueFontSize || config.valueFontSize || 13;
  const valueColor = element.valueColor || config.valueColor || "#000000";

  let displayValue = raw || "-";
  if (raw && element.dateFormat) {
    try {
      const d = new Date(raw);
      if (!isNaN(d.getTime())) {
        displayValue = element.dateFormat
          .replace("YYYY", String(d.getFullYear()))
          .replace("MM", String(d.getMonth() + 1).padStart(2, "0"))
          .replace("DD", String(d.getDate()).padStart(2, "0"));
      }
    } catch {
      displayValue = raw;
    }
  }

  return (
    <div className="flex flex-col py-1" style={{ gridColumn: `span ${element.colspan || 1}` }}>
      <span className="font-medium mb-0.5" style={{ fontSize: `${labelFontSize}px`, color: labelColor }}>
        {element.label}
      </span>
      <span style={{ fontSize: `${valueFontSize}px`, color: valueColor }}>{displayValue}</span>
    </div>
  );
}

function CardLinkRenderer({
  element,
  getQueryResult,
  queryId,
}: {
  element: CardLinkElement;
  getQueryResult: (id: string) => QueryResult | null;
  queryId?: string;
}) {
  const url = getFieldValue(element.columnName, queryId, getQueryResult);
  const text = element.linkText || url || element.label;

  return (
    <div className="flex items-center py-1" style={{ gridColumn: `span ${element.colspan || 1}` }}>
      <span className="text-sm text-gray-600 mr-2">{element.label}</span>
      {url ? (
        <a
          href={url}
          target={element.openInNewTab ? "_blank" : undefined}
          rel={element.openInNewTab ? "noopener noreferrer" : undefined}
          className="text-sm text-blue-600 hover:underline truncate"
        >
          {text}
        </a>
      ) : (
        <span className="text-sm text-gray-400">-</span>
      )}
    </div>
  );
}

function CardStatusRenderer({
  element,
  getQueryResult,
  queryId,
}: {
  element: CardStatusElement;
  getQueryResult: (id: string) => QueryResult | null;
  queryId?: string;
}) {
  const value = getFieldValue(element.columnName, queryId, getQueryResult);
  const mapping = element.statusMappings?.find((m) => m.value === value);
  const dotColor = mapping?.color || "#9ca3af";
  const label = mapping?.label || value || "-";

  return (
    <div className="flex items-center gap-2 py-1" style={{ gridColumn: `span ${element.colspan || 1}` }}>
      <span
        className="inline-block w-2 h-2 rounded-full flex-shrink-0"
        style={{ backgroundColor: dotColor }}
      />
      <span className="text-sm">{label}</span>
    </div>
  );
}

function CardStaticTextRenderer({ element }: { element: CardStaticTextElement }) {
  return (
    <div style={{ gridColumn: `span ${element.colspan || 1}` }}>
      <span
        style={{
          fontSize: `${element.fontSize || 13}px`,
          color: element.color || "#000000",
          fontWeight: element.fontWeight || "normal",
          textAlign: element.textAlign || "left",
          display: "block",
        }}
      >
        {element.text}
      </span>
    </div>
  );
}

function CardElementRenderer({
  element,
  getQueryResult,
  queryId,
  config,
}: ElementRendererProps) {
  switch (element.type) {
    case "header":
      return <CardHeaderRenderer element={element} config={config} />;
    case "dataCell":
      return (
        <CardDataCellRenderer
          element={element}
          getQueryResult={getQueryResult}
          queryId={queryId}
          config={config}
        />
      );
    case "divider":
      return <CardDividerRenderer element={element} config={config} />;
    case "badge":
      return (
        <CardBadgeRenderer
          element={element}
          getQueryResult={getQueryResult}
          queryId={queryId}
          config={config}
        />
      );
    case "image":
      return <CardImageRenderer element={element as CardImageElement} getQueryResult={getQueryResult} queryId={queryId} />;
    case "number":
      return <CardNumberRenderer element={element as CardNumberElement} getQueryResult={getQueryResult} queryId={queryId} config={config} />;
    case "date":
      return <CardDateRenderer element={element as CardDateElement} getQueryResult={getQueryResult} queryId={queryId} config={config} />;
    case "link":
      return <CardLinkRenderer element={element as CardLinkElement} getQueryResult={getQueryResult} queryId={queryId} />;
    case "status":
      return <CardStatusRenderer element={element as CardStatusElement} getQueryResult={getQueryResult} queryId={queryId} />;
    case "spacer":
      return <div key={element.id} style={{ height: (element as CardSpacerElement).height || 16, gridColumn: `span ${element.colspan || 1}` }} />;
    case "staticText":
      return <CardStaticTextRenderer element={element as CardStaticTextElement} />;
    default:
      return null;
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// v3 그리드 렌더러
// ─────────────────────────────────────────────────────────────────────────────
function CardGridRenderer({
  config,
  getQueryResult,
  queryId,
}: {
  config: CardLayoutConfig;
  getQueryResult: (queryId: string) => QueryResult | null;
  queryId?: string;
}) {
  return (
    <div
      className="flex h-full w-full flex-col overflow-hidden"
      style={{
        padding: config.padding || "8px",
        backgroundColor: config.backgroundColor || "#ffffff",
        borderRadius: config.borderRadius || "0",
        border: config.borderStyle !== "none"
          ? `${config.borderWidth || 1}px ${config.borderStyle || "solid"} ${config.borderColor || "#e5e7eb"}`
          : "none",
        ...(config.accentBorderWidth && config.accentBorderWidth > 0
          ? { borderLeft: `${config.accentBorderWidth}px solid ${config.accentBorderColor || "#3b82f6"}` }
          : {}),
      }}
    >
      <div
        className="flex-1 overflow-auto"
        style={{ display: "flex", flexDirection: "column", gap: config.gap || "0px" }}
      >
        {config.rows.map((row: CardLayoutRow) => (
          <div
            key={row.id}
            className="grid"
            style={{
              gridTemplateColumns: `repeat(${row.gridColumns}, 1fr)`,
              height: row.height || "auto",
              gap: config.gap || "0px",
              marginBottom: row.marginBottom || undefined,
            }}
          >
            {row.elements.map((element: CardElement) => (
              <CardElementRenderer
                key={element.id}
                element={element}
                getQueryResult={getQueryResult}
                queryId={queryId}
                config={config}
              />
            ))}
          </div>
        ))}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// 메인 컴포넌트
// ─────────────────────────────────────────────────────────────────────────────
export function CardRenderer({ component, getQueryResult }: CardRendererProps) {
  const effectiveQueryId = component.queryId || `card_${component.id}`;

  if (component.cardLayoutConfig) {
    return (
      <CardGridRenderer
        config={component.cardLayoutConfig}
        getQueryResult={getQueryResult}
        queryId={effectiveQueryId}
      />
    );
  }

  return (
    <CardListRenderer component={component} getQueryResult={getQueryResult} />
  );
}
