"use client";

import React from "react";
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  Legend,
  Line,
  LineChart,
  Pie,
  PieChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import type { ComponentRendererProps } from "@/types/component";
import { filterDOMProps } from "@/lib/utils/domPropsFilter";
import { useChartData } from "./use-chart-data";
import type { ChartConfig, ChartType } from "./types";

/**
 * Chart — canonical 차트 컴포넌트 (Phase G.3)
 *
 * `dataSource.tableName + groupBy + aggregation` 으로 `/aggregate-group` 호출,
 * recharts 위에서 4종 차트 (bar / horizontalBar / line / donut) 렌더.
 *
 * 디자인 모드: API 호출 안 함. 정적 preview row 4 개로 모양만 보여줌.
 * dataSource 미완성: 같은 preview 로 fallback.
 * 운영 모드 fetch 실패: error message 표시.
 */

const VALID_TYPES: ChartType[] = ["bar", "horizontalBar", "line", "donut"];

const DEFAULT_PALETTE = [
  "#6c5ce7", // primary purple
  "#00cec9", // cyan
  "#fd79a8", // pink
  "#fdcb6e", // amber
  "#74b9ff", // soft blue
  "#55efc4", // mint
  "#a29bfe", // lavender
  "#ffeaa7", // pale yellow
];

export interface ChartComponentProps extends ComponentRendererProps {
  config?: ChartConfig;
}

export const ChartComponent: React.FC<ChartComponentProps> = ({
  component,
  isDesignMode = false,
  isSelected = false,
  onClick,
  onDragStart,
  onDragEnd,
  config,
  className,
  style,
  ...props
}) => {
  const p = props as any;
  const fromProps: Partial<ChartConfig> = {};
  if (typeof p.chartType === "string" && (VALID_TYPES as string[]).includes(p.chartType))
    fromProps.chartType = p.chartType as ChartType;
  if (typeof p.title === "string") fromProps.title = p.title;
  if (p.dataSource && typeof p.dataSource === "object") fromProps.dataSource = p.dataSource;
  if (typeof p.includeEmptyGroup === "boolean") fromProps.includeEmptyGroup = p.includeEmptyGroup;
  if (typeof p.barColor === "string") fromProps.barColor = p.barColor;
  if (Array.isArray(p.donutPalette)) fromProps.donutPalette = p.donutPalette;
  if (typeof p.showAxis === "boolean") fromProps.showAxis = p.showAxis;
  if (typeof p.showLegend === "boolean") fromProps.showLegend = p.showLegend;

  const componentConfig = {
    ...config,
    ...((component as any).config ?? {}),
    ...((component as any).componentConfig ?? {}),
    ...fromProps,
  } as ChartConfig;

  const chartType: ChartType = (VALID_TYPES as string[]).includes(
    componentConfig.chartType as string,
  )
    ? (componentConfig.chartType as ChartType)
    : "bar";

  const title = componentConfig.title;
  const barColor = componentConfig.barColor || "#6c5ce7";
  const donutPalette =
    componentConfig.donutPalette && componentConfig.donutPalette.length > 0
      ? componentConfig.donutPalette
      : DEFAULT_PALETTE;
  const showAxis = componentConfig.showAxis ?? true;
  const showLegend = componentConfig.showLegend ?? true;

  const userContext = React.useMemo(
    () => ({
      companyCode: (p.companyCode as string) || undefined,
      userId: (p.userId as string) || undefined,
      deptCode: (p.deptCode as string) || undefined,
      userName: (p.userName as string) || undefined,
    }),
    [p.companyCode, p.userId, p.deptCode, p.userName],
  );

  const { rows, loading, error, isPreview } = useChartData(componentConfig.dataSource, {
    isDesignMode,
    formData: (p.formData as Record<string, unknown>) || undefined,
    userContext,
    refreshKey: (p.refreshKey as number | string | undefined) || undefined,
    includeEmptyGroup: componentConfig.includeEmptyGroup,
  });

  const containerStyle: React.CSSProperties = {
    width: "100%",
    height: "100%",
    display: "flex",
    flexDirection: "column",
    boxSizing: "border-box",
    background: "hsl(var(--card))",
    border: "1px solid hsl(var(--border))",
    borderRadius: 8,
    padding: 12,
    minHeight: 200,
    ...((component as any).style ?? {}),
    ...style,
  };

  if (isDesignMode && isSelected) {
    containerStyle.outline = "2px solid hsl(var(--primary))";
    containerStyle.outlineOffset = "2px";
  }

  const handleClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    onClick?.();
  };

  /* eslint-disable @typescript-eslint/no-unused-vars */
  const {
    selectedScreen: _1, onZoneComponentDrop: _2, onZoneClick: _3,
    componentConfig: _4, component: _5, isSelected: _6,
    onClick: _7, onDragStart: _8, onDragEnd: _9,
    size: _10, position: _11, style: _12,
    screenId: _13, tableName: _14, onRefresh: _15, onClose: _16,
    web_type: _17, autoGeneration: _18, isInteractive: _19,
    formData: _20, onFormDataChange: _21,
    menuId: _22, menuObjid: _23, onSave: _24,
    userId: _25, userName: _26, companyCode: _27, deptCode: _27b,
    isInModal: _28, readonly: _29, originalData: _30,
    selectedRows: _36, selectedRowsData: _37, onSelectedRowsChange: _38,
    sortBy: _39, sortOrder: _40, tableDisplayData: _41,
    flowSelectedData: _42, flowSelectedStepId: _43, onFlowSelectedDataChange: _44,
    onConfigChange: _45, refreshKey: _46, flowRefreshKey: _47, onFlowRefresh: _48,
    isPreview: _49, groupedData: _50,
    chartType: _51, title: _52, dataSource: _53,
    includeEmptyGroup: _54, barColor: _55, donutPalette: _56,
    showAxis: _57, showLegend: _58,
    disabled: _59, required: _60,
    ...domProps
  } = props as any;
  /* eslint-enable @typescript-eslint/no-unused-vars */

  // recharts 데이터 형식 (group/value → name/value)
  const data = React.useMemo(
    () =>
      rows.map((r) => ({
        name: r.group === null || r.group === "" ? "—" : String(r.group),
        value: r.value,
      })),
    [rows],
  );

  const renderChart = (): React.ReactNode => {
    if (data.length === 0) {
      return (
        <div
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            flex: 1,
            color: "hsl(var(--muted-foreground))",
            fontSize: 12,
          }}
        >
          {error ? `데이터 로드 실패: ${error}` : "표시할 데이터가 없습니다."}
        </div>
      );
    }

    switch (chartType) {
      case "donut":
        return (
          <ResponsiveContainer width="100%" height="100%">
            <PieChart>
              <Pie
                data={data}
                dataKey="value"
                nameKey="name"
                innerRadius="55%"
                outerRadius="85%"
                paddingAngle={2}
              >
                {data.map((_, i) => (
                  <Cell key={i} fill={donutPalette[i % donutPalette.length]} />
                ))}
              </Pie>
              <Tooltip />
              {showLegend && <Legend verticalAlign="bottom" height={24} />}
            </PieChart>
          </ResponsiveContainer>
        );
      case "horizontalBar":
        return (
          <ResponsiveContainer width="100%" height="100%">
            <BarChart data={data} layout="vertical" margin={{ top: 8, right: 16, left: 8, bottom: 8 }}>
              <CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border))" />
              {showAxis && <XAxis type="number" stroke="hsl(var(--muted-foreground))" fontSize={11} />}
              {showAxis && (
                <YAxis dataKey="name" type="category" stroke="hsl(var(--muted-foreground))" fontSize={11} width={80} />
              )}
              <Tooltip />
              <Bar dataKey="value" fill={barColor} radius={[0, 4, 4, 0]} />
            </BarChart>
          </ResponsiveContainer>
        );
      case "line":
        return (
          <ResponsiveContainer width="100%" height="100%">
            <LineChart data={data} margin={{ top: 8, right: 16, left: 8, bottom: 8 }}>
              <CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border))" />
              {showAxis && <XAxis dataKey="name" stroke="hsl(var(--muted-foreground))" fontSize={11} />}
              {showAxis && <YAxis stroke="hsl(var(--muted-foreground))" fontSize={11} />}
              <Tooltip />
              <Line type="monotone" dataKey="value" stroke={barColor} strokeWidth={2} dot={{ r: 3 }} />
            </LineChart>
          </ResponsiveContainer>
        );
      case "bar":
      default:
        return (
          <ResponsiveContainer width="100%" height="100%">
            <BarChart data={data} margin={{ top: 8, right: 16, left: 8, bottom: 8 }}>
              <CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border))" />
              {showAxis && <XAxis dataKey="name" stroke="hsl(var(--muted-foreground))" fontSize={11} />}
              {showAxis && <YAxis stroke="hsl(var(--muted-foreground))" fontSize={11} />}
              <Tooltip />
              <Bar dataKey="value" fill={barColor} radius={[4, 4, 0, 0]} />
            </BarChart>
          </ResponsiveContainer>
        );
    }
  };

  return (
    <div
      style={containerStyle}
      className={className}
      onClick={handleClick}
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      {...filterDOMProps(domProps)}
    >
      {(title || isPreview || loading) && (
        <div
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            fontSize: 12,
            fontWeight: 700,
            color: "hsl(var(--foreground))",
            marginBottom: 6,
            flexShrink: 0,
          }}
        >
          <span>{title || (isPreview ? "차트 (미리보기)" : "")}</span>
          {loading && (
            <span style={{ fontSize: 10, color: "hsl(var(--muted-foreground))", fontWeight: 500 }}>
              로딩…
            </span>
          )}
        </div>
      )}
      <div style={{ flex: 1, minHeight: 0 }}>{renderChart()}</div>
    </div>
  );
};

export const ChartWrapper: React.FC<ChartComponentProps> = (props) => {
  return <ChartComponent {...props} />;
};
