"use client";

import React, { ReactNode } from "react";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { cn } from "@/lib/utils";

// 컬럼 정의 타입
export interface RDVColumn<T> {
  key: string;
  label: string;
  width?: string;
  render?: (value: any, row: T, index: number) => ReactNode;
  hideOnMobile?: boolean;
  className?: string;
}

// 카드 필드 타입
export interface RDVCardField<T> {
  label: string;
  render: (item: T) => ReactNode;
  hideEmpty?: boolean;
}

// 메인 Props 타입
export interface ResponsiveDataViewProps<T> {
  data: T[];
  columns: RDVColumn<T>[];
  keyExtractor: (item: T) => string;

  // 로딩/빈 상태
  isLoading?: boolean;
  emptyMessage?: string;
  skeletonCount?: number;

  // 카드 설정 (모바일)
  cardTitle: (item: T) => ReactNode;
  cardSubtitle?: (item: T) => ReactNode;
  cardHeaderRight?: (item: T) => ReactNode;
  cardFields?: RDVCardField<T>[] | ((item: T) => RDVCardField<T>[]);

  // 액션 (테이블 마지막 컬럼 + 카드 하단)
  renderActions?: (item: T) => ReactNode;
  actionsLabel?: string;
  actionsWidth?: string;

  // 행 클릭
  onRowClick?: (item: T) => void;

  // 스타일 커스터마이징
  tableContainerClassName?: string;
  cardContainerClassName?: string;
}

// 중첩 객체에서 키 경로로 값을 꺼내는 헬퍼
function getNestedValue(obj: any, path: string): any {
  return path.split(".").reduce((acc, key) => acc?.[key], obj);
}

export function ResponsiveDataView<T>({
  data,
  columns,
  keyExtractor,
  isLoading = false,
  emptyMessage,
  skeletonCount = 5,
  cardTitle,
  cardSubtitle,
  cardHeaderRight,
  cardFields,
  renderActions,
  actionsLabel,
  actionsWidth,
  onRowClick,
  tableContainerClassName,
  cardContainerClassName,
}: ResponsiveDataViewProps<T>) {
  // cardFields 미지정 시 columns에서 자동 생성
  function resolveCardFields(item: T): RDVCardField<T>[] {
    if (typeof cardFields === "function") return cardFields(item);
    if (Array.isArray(cardFields)) return cardFields;
    return columns
      .filter((col) => !col.hideOnMobile)
      .map((col) => ({
        label: col.label,
        render: (row: T) =>
          col.render
            ? col.render(getNestedValue(row, col.key), row, 0)
            : String(getNestedValue(row, col.key) ?? "-"),
      }));
  }

  // --- 로딩 스켈레톤 ---
  if (isLoading) {
    return (
      <>
        {/* 데스크톱 테이블 스켈레톤 */}
        <div
          className={cn(
            "hidden rounded-lg border bg-card shadow-sm lg:block",
            tableContainerClassName
          )}
        >
          <Table>
            <TableHeader>
              <TableRow className="border-b bg-muted/50 hover:bg-muted/50">
                {columns.map((col) => (
                  <TableHead
                    key={col.key}
                    style={col.width ? { width: col.width } : undefined}
                    className="h-12 text-sm font-semibold"
                  >
                    {col.label}
                  </TableHead>
                ))}
                {renderActions && (
                  <TableHead
                    style={{ width: actionsWidth || "120px" }}
                    className="h-12 text-sm font-semibold"
                  >
                    {actionsLabel || "작업"}
                  </TableHead>
                )}
              </TableRow>
            </TableHeader>
            <TableBody>
              {Array.from({ length: skeletonCount }).map((_, rowIdx) => (
                <TableRow key={rowIdx} className="border-b">
                  {columns.map((col) => (
                    <TableCell key={col.key} className="h-16">
                      <div className="h-4 animate-pulse rounded bg-muted" />
                    </TableCell>
                  ))}
                  {renderActions && (
                    <TableCell className="h-16">
                      <div className="flex gap-2">
                        <div className="h-8 w-8 animate-pulse rounded bg-muted" />
                        <div className="h-8 w-8 animate-pulse rounded bg-muted" />
                      </div>
                    </TableCell>
                  )}
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>

        {/* 모바일 카드 스켈레톤 */}
        <div
          className={cn(
            "grid gap-4 sm:grid-cols-2 lg:hidden",
            cardContainerClassName
          )}
        >
          {Array.from({ length: skeletonCount }).map((_, i) => (
            <div
              key={i}
              className="rounded-lg border bg-card p-4 shadow-sm"
            >
              <div className="mb-3 flex items-start justify-between">
                <div className="flex-1 space-y-2">
                  <div className="h-5 w-32 animate-pulse rounded bg-muted" />
                  <div className="h-4 w-24 animate-pulse rounded bg-muted" />
                </div>
                <div className="h-6 w-12 animate-pulse rounded bg-muted" />
              </div>
              <div className="space-y-2 border-t pt-3">
                {Array.from({ length: 3 }).map((_, j) => (
                  <div key={j} className="flex justify-between">
                    <div className="h-4 w-16 animate-pulse rounded bg-muted" />
                    <div className="h-4 w-24 animate-pulse rounded bg-muted" />
                  </div>
                ))}
              </div>
              {renderActions && (
                <div className="mt-3 flex gap-2 border-t pt-3">
                  <div className="h-9 flex-1 animate-pulse rounded bg-muted" />
                  <div className="h-9 flex-1 animate-pulse rounded bg-muted" />
                </div>
              )}
            </div>
          ))}
        </div>
      </>
    );
  }

  // --- 빈 상태 ---
  if (data.length === 0) {
    return (
      <div className="flex h-32 items-center justify-center rounded-lg border bg-card text-sm text-muted-foreground">
        {emptyMessage || "데이터가 없습니다."}
      </div>
    );
  }

  // --- 실제 데이터 렌더링 ---
  return (
    <>
      {/* 데스크톱 테이블 (lg 이상) */}
      <div
        className={cn(
          "hidden rounded-lg border bg-card shadow-sm lg:block",
          tableContainerClassName
        )}
      >
        <Table>
          <TableHeader>
            <TableRow className="border-b bg-muted/50 hover:bg-muted/50">
              {columns.map((col) => (
                <TableHead
                  key={col.key}
                  style={col.width ? { width: col.width } : undefined}
                  className="h-12 text-sm font-semibold"
                >
                  {col.label}
                </TableHead>
              ))}
              {renderActions && (
                <TableHead
                  style={{ width: actionsWidth || "120px" }}
                  className="h-12 text-sm font-semibold"
                >
                  {actionsLabel || "작업"}
                </TableHead>
              )}
            </TableRow>
          </TableHeader>
          <TableBody>
            {data.map((item, index) => (
              <TableRow
                key={keyExtractor(item) ?? `row-${index}`}
                className={cn(
                  "border-b transition-colors hover:bg-muted/50",
                  onRowClick && "cursor-pointer"
                )}
                onClick={() => onRowClick?.(item)}
              >
                {columns.map((col) => (
                  <TableCell
                    key={col.key}
                    className={cn("h-16 text-sm", col.className)}
                  >
                    {col.render
                      ? col.render(getNestedValue(item, col.key), item, index)
                      : String(getNestedValue(item, col.key) ?? "-")}
                  </TableCell>
                ))}
                {renderActions && (
                  <TableCell className="h-16 text-sm">
                    <div className="flex gap-2">{renderActions(item)}</div>
                  </TableCell>
                )}
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </div>

      {/* 모바일 카드 (lg 미만) */}
      <div
        className={cn(
          "grid gap-4 sm:grid-cols-2 lg:hidden",
          cardContainerClassName
        )}
      >
        {data.map((item, index) => {
          const fields = resolveCardFields(item);
          return (
            <div
              key={keyExtractor(item) ?? `card-${index}`}
              className={cn(
                "rounded-lg border bg-card p-4 shadow-sm transition-colors hover:bg-muted/50",
                onRowClick && "cursor-pointer"
              )}
              onClick={() => onRowClick?.(item)}
            >
              {/* 카드 헤더 */}
              <div className="mb-3 flex items-start justify-between">
                <div className="min-w-0 flex-1">
                  <h3 className="truncate text-base font-semibold">
                    {cardTitle(item)}
                  </h3>
                  {cardSubtitle && (
                    <p className="mt-0.5 truncate text-sm text-muted-foreground">
                      {cardSubtitle(item)}
                    </p>
                  )}
                </div>
                {cardHeaderRight && (
                  <div className="ml-2 shrink-0">{cardHeaderRight(item)}</div>
                )}
              </div>

              {/* 카드 필드 */}
              {fields.length > 0 && (
                <div className="space-y-1.5 border-t pt-3">
                  {fields.map((field, i) => (
                    <div key={i} className="flex justify-between text-sm">
                      <span className="text-muted-foreground">
                        {field.label}
                      </span>
                      <span className="font-medium">{field.render(item)}</span>
                    </div>
                  ))}
                </div>
              )}

              {/* 카드 액션 */}
              {renderActions && (
                <div className="mt-3 flex gap-2 border-t pt-3">
                  {renderActions(item)}
                </div>
              )}
            </div>
          );
        })}
      </div>
    </>
  );
}

