"use client";

import { ReactNode } from "react";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { ChevronLeft, ChevronRight, LucideIcon } from "lucide-react";
import { StatusBadge, StatusType } from "@/components/molecules/StatusBadge";
import { IconWithBadge } from "@/components/molecules/IconWithBadge";
import { TableActions, TableAction } from "@/components/molecules/TableActions";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";

// 셀 타입 정의
export type CellType =
  | "text"           // 일반 텍스트
  | "number"         // 숫자 (우측 정렬)
  | "currency"       // 통화 (₩ 표시)
  | "date"           // 날짜
  | "datetime"       // 날짜 + 시간
  | "status"         // 상태 배지
  | "badge"          // 일반 배지
  | "icon"           // 아이콘
  | "iconBadge"      // 아이콘 + 배지
  | "actions"        // 액션 버튼들
  | "custom";        // 커스텀 렌더링

export interface Column<T> {
  key: keyof T | string;
  label: string;
  type?: CellType;
  width?: string;
  align?: "left" | "center" | "right";
  sortable?: boolean;
  className?: string;

  // 타입별 설정
  statusConfig?: {
    showDot?: boolean;
  };
  badgeConfig?: {
    variant?: "default" | "secondary" | "destructive" | "outline";
    className?: string;
  };
  iconConfig?: {
    iconColor?: string;
    iconBgColor?: string;
    size?: "sm" | "md" | "lg";
  };
  currencyConfig?: {
    locale?: string;
    currency?: string;
  };
  dateConfig?: {
    format?: "short" | "long" | "relative";
  };

  // 커스텀 렌더링
  render?: (value: any, row: T, index?: number) => ReactNode;

  // 값 변환
  format?: (value: any) => string | number;
}

interface DataTableProps<T extends object> {
  columns: Column<T>[];
  data: T[];
  keyField: keyof T;
  onRowClick?: (row: T) => void;
  loading?: boolean;
  emptyMessage?: string;
  pagination?: {
    currentPage: number;
    totalPages: number;
    onPageChange: (page: number) => void;
    showInfo?: boolean;
  };
  striped?: boolean;
  hoverable?: boolean;
  compact?: boolean;
}

// 셀 렌더러
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- 다양한 셀 타입(text/date/icon/badge 등)을 다형적으로 처리
function renderCell<T>(column: Column<T>, value: any, row: T, index?: number): ReactNode {
  // 값 포맷팅 또는 render 호출
  let formattedValue: any;

  if (column.render) {
    formattedValue = column.render(value, row, index);
  } else if (column.format) {
    formattedValue = column.format(value);
  } else {
    formattedValue = value;
  }

  // 타입별 렌더링
  switch (column.type) {
    case "number":
      return <span className="font-mono">{formattedValue?.toLocaleString()}</span>;

    case "currency":
      const locale = column.currencyConfig?.locale || "ko-KR";
      const currency = column.currencyConfig?.currency || "KRW";
      const currencyValue = typeof formattedValue === "number"
        ? formattedValue.toLocaleString(locale, { style: "currency", currency })
        : formattedValue;
      return <span className="font-mono">{currencyValue}</span>;

    case "date":
      if (!formattedValue) return "-";
      const dateValue = new Date(formattedValue);
      return <span className="text-sm">{dateValue.toLocaleDateString("ko-KR")}</span>;

    case "datetime":
      if (!formattedValue) return "-";
      const datetimeValue = new Date(formattedValue);
      return (
        <span className="text-sm">
          {datetimeValue.toLocaleDateString("ko-KR")} {datetimeValue.toLocaleTimeString("ko-KR", { hour: "2-digit", minute: "2-digit" })}
        </span>
      );

    case "status":
      return (
        <StatusBadge
          label={formattedValue as string}
          variant={formattedValue as StatusType}
          showDot={column.statusConfig?.showDot}
        />
      );

    case "badge":
      return (
        <Badge
          variant={column.badgeConfig?.variant}
          className={column.badgeConfig?.className}
        >
          {formattedValue}
        </Badge>
      );

    case "icon":
      const IconComponent = formattedValue as LucideIcon;
      return IconComponent ? (
        <IconWithBadge
          icon={IconComponent}
          iconColor={column.iconConfig?.iconColor}
          iconBgColor={column.iconConfig?.iconBgColor}
          size={column.iconConfig?.size}
        />
      ) : null;

    case "iconBadge":
      // value should be { icon, label, badge }
      if (typeof formattedValue === "object" && formattedValue.icon) {
        return (
          <IconWithBadge
            icon={formattedValue.icon}
            label={formattedValue.label}
            badge={formattedValue.badge}
            iconColor={column.iconConfig?.iconColor}
            iconBgColor={column.iconConfig?.iconBgColor}
            size={column.iconConfig?.size}
          />
        );
      }
      return formattedValue;

    case "actions":
      // render 함수가 TableAction[] 배열을 반환해야 함
      const actions = Array.isArray(formattedValue) ? formattedValue : [];
      return actions.length > 0 ? <TableActions actions={actions} /> : null;

    case "custom":
      // 커스텀 타입은 이미 render 함수에서 처리됨
      return formattedValue;

    case "text":
    default:
      return formattedValue ?? "-";
  }
}

// 정렬 함수
function getAlignClass<T>(column: Column<T>): string {
  if (column.align) {
    return column.align === "center" ? "text-center" : column.align === "right" ? "text-right" : "text-left";
  }

  // 타입별 기본 정렬
  switch (column.type) {
    case "number":
    case "currency":
    case "actions":
      return "text-right";
    case "status":
    case "badge":
    case "icon":
    case "iconBadge":
      return "text-center";
    default:
      return "text-left";
  }
}

export function DataTable<T extends object>({
  columns,
  data,
  keyField,
  onRowClick,
  loading,
  emptyMessage = "데이터가 없습니다.",
  pagination,
  striped = false,
  hoverable = true,
  compact = false
}: DataTableProps<T>) {
  return (
    <Card className="hidden md:block">
      <CardContent className="p-0">
        <div className="overflow-x-auto">
          <Table>
            <TableHeader>
              <TableRow>
                {columns.map((column) => (
                  <TableHead
                    key={String(column.key)}
                    className={cn(
                      getAlignClass(column),
                      column.className,
                      column.width && `w-[${column.width}]`
                    )}
                  >
                    {column.label}
                  </TableHead>
                ))}
              </TableRow>
            </TableHeader>
            <TableBody>
              {loading ? (
                <TableRow>
                  <TableCell colSpan={columns.length} className="text-center py-8 text-muted-foreground">
                    로딩 중...
                  </TableCell>
                </TableRow>
              ) : data.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={columns.length} className="text-center py-8 text-muted-foreground">
                    {emptyMessage}
                  </TableCell>
                </TableRow>
              ) : (
                data.map((row, rowIndex) => (
                  <TableRow
                    key={row[keyField] ? String(row[keyField]) : `row-${rowIndex}`}
                    onClick={() => onRowClick?.(row)}
                    className={cn(
                      onRowClick && "cursor-pointer",
                      hoverable && "hover:bg-muted/50",
                      striped && rowIndex % 2 === 1 && "bg-muted/20",
                      compact && "h-10"
                    )}
                  >
                    {columns.map((column) => {
                      const value = column.key in row ? row[column.key as keyof T] : null;
                      return (
                        <TableCell
                          key={String(column.key)}
                          className={cn(
                            getAlignClass(column),
                            column.className,
                            compact && "py-2"
                          )}
                        >
                          {renderCell(column, value, row, rowIndex)}
                        </TableCell>
                      );
                    })}
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </div>

        {pagination && pagination.totalPages > 1 && (
          <div className="flex items-center justify-between p-4 border-t">
            {pagination.showInfo !== false && (
              <p className="text-sm text-muted-foreground">
                페이지 {pagination.currentPage} / {pagination.totalPages}
              </p>
            )}
            <div className="flex gap-2 ml-auto">
              <Button
                variant="outline"
                size="sm"
                onClick={() => pagination.onPageChange(pagination.currentPage - 1)}
                disabled={pagination.currentPage === 1}
              >
                <ChevronLeft className="w-4 h-4" />
              </Button>
              <Button
                variant="outline"
                size="sm"
                onClick={() => pagination.onPageChange(pagination.currentPage + 1)}
                disabled={pagination.currentPage === pagination.totalPages}
              >
                <ChevronRight className="w-4 h-4" />
              </Button>
            </div>
          </div>
        )}
      </CardContent>
    </Card>
  );
}