import type { ColumnDef, Row } from "@tanstack/react-table";
import { ClientDataTableColumnHeaderSimple } from "../client-data-table/data-table-column-simple-header";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Ellipsis } from "lucide-react";
import { formatDate } from "@/lib/utils";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuRadioGroup,
  DropdownMenuRadioItem,
  DropdownMenuSeparator,
  DropdownMenuShortcut,
  DropdownMenuSub,
  DropdownMenuSubContent,
  DropdownMenuSubTrigger,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { toast } from 'sonner';

/** row 액션 관련 타입 */
export interface DataTableRowAction<TData> {
  row: Row<TData>;
  type: "open" | "edit" | "update";
}

/** 컬럼 타입 (필요에 따라 확장) */
export type ColumnType = "STRING" | "NUMBER" | "LIST";

export interface DataTableColumnJSON {
  key: string;
  /** 실제 Excel 등에서 구분용으로 쓰이는 label (고정) */
  label: string;

  /** UI 표시용 label (예: 단위를 함께 표시) */
  displayLabel?: string;

  type: ColumnType;
  options?: string[];
  uom?: string;
  uomId?: string;
  shi?: boolean;
}

/**
 * getColumns 함수에 필요한 props
 * - TData: 테이블에 표시할 행(Row)의 타입
 */
interface GetColumnsProps<TData> {
  columnsJSON: DataTableColumnJSON[];
  setRowAction: React.Dispatch<
    React.SetStateAction<DataTableRowAction<TData> | null>
  >;
  setReportData: React.Dispatch<React.SetStateAction<{ [key: string]: any }[]>>;
  tempCount: number;
  // 체크박스 선택 관련 props
  selectedRows?: Record<string, boolean>;
  onRowSelectionChange?: (updater: Record<string, boolean> | ((prev: Record<string, boolean>) => Record<string, boolean>)) => void;
  editableFieldsMap?: Map<string, string[]>; // 새로 추가
}

/**
 * getColumns 함수
 * 1) columnsJSON 배열을 순회하면서 accessorKey / header / cell 등을 설정
 * 2) 체크박스 컬럼 추가 (showBatchSelection이 true일 때)
 * 3) 마지막에 "Action" 칼럼(예: update 버튼) 추가
 */
export function getColumns<TData extends object>({
  columnsJSON,
  setRowAction,
  setReportData,
  tempCount,
  selectedRows = {},
  onRowSelectionChange,
  editableFieldsMap = new Map(), // 새로 추가
}: GetColumnsProps<TData>): ColumnDef<TData>[] {
  const columns: ColumnDef<TData>[] = [];

  // (1) 체크박스 컬럼 (항상 표시)
  const selectColumn: ColumnDef<TData> = {
    id: "select",
    header: ({ table }) => (
      <Checkbox
        checked={
          table.getIsAllPageRowsSelected() ||
          (table.getIsSomePageRowsSelected() && "indeterminate")
        }
        onCheckedChange={(value) => {
          table.toggleAllPageRowsSelected(!!value);
          
          // 모든 행 선택/해제
          if (onRowSelectionChange) {
            const allRowsSelection: Record<string, boolean> = {};
            table.getRowModel().rows.forEach((row) => {
              allRowsSelection[row.id] = !!value;
            });
            onRowSelectionChange(allRowsSelection);
          }
        }}
        aria-label="Select all"
        className="translate-y-[2px]"
      />
    ),
    cell: ({ row }) => (
      <Checkbox
        checked={row.getIsSelected()}
        onCheckedChange={(value) => {
          row.toggleSelected(!!value);
          
          // 개별 행 선택 상태 업데이트
          if (onRowSelectionChange) {
            onRowSelectionChange(prev => ({
              ...prev,
              [row.id]: !!value
            }));
          }
        }}
        aria-label="Select row"
        className="translate-y-[2px]"
      />
    ),
    enableSorting: false,
    enableHiding: false,
    size: 40,
  };
  columns.push(selectColumn);

  // (2) 기본 컬럼들
  const baseColumns: ColumnDef<TData>[] = columnsJSON.map((col) => ({
    accessorKey: col.key,
    header: ({ column }) => (
      <ClientDataTableColumnHeaderSimple
        column={column}
        title={col.displayLabel || col.label}
      />
    ),

    meta: {
      excelHeader: col.label,
      minWidth: 80,
      paddingFactor: 1.2,
      maxWidth: col.key === "TAG_NO" ? 120 : 150,
      isReadOnly: col.shi === true,
    },
    
    cell: ({ row }) => {
      const cellValue = row.getValue(col.key);
      
      // 기본 읽기 전용 여부 (shi 속성 기반)
      let isReadOnly = col.shi === true;
      
      // 동적 읽기 전용 여부 계산
      if (!isReadOnly && col.key !== 'TAG_NO' && col.key !== 'TAG_DESC') {
        const tagNo = row.getValue('TAG_NO') as string;
        if (tagNo && editableFieldsMap.has(tagNo)) {
          const editableFields = editableFieldsMap.get(tagNo) || [];
          // 해당 TAG의 편집 가능 필드 목록에 없으면 읽기 전용
          isReadOnly = !editableFields.includes(col.key);
        } else {
          // TAG_NO가 없거나 editableFieldsMap에 없으면 읽기 전용
          isReadOnly = true;
        }
      }
      
      const readOnlyClass = isReadOnly ? "read-only-cell" : "";
      const cellStyle = isReadOnly 
        ? { backgroundColor: '#f5f5f5', color: '#666', cursor: 'not-allowed' } 
        : {};

      // 툴팁 메시지 설정
      let tooltipMessage = "";
      if (isReadOnly) {
        if (col.shi === true) {
          tooltipMessage = "SHI 전용 필드입니다";
        } else if (col.key === 'TAG_NO' || col.key === 'TAG_DESC') {
          tooltipMessage = "기본 필드는 수정할 수 없습니다";
        } else {
          tooltipMessage = "이 TAG 클래스에서는 편집할 수 없는 필드입니다";
        }
      }

      // 데이터 타입별 처리
      switch (col.type) {
        case "NUMBER":
          return (
            <div 
              className={readOnlyClass} 
              style={cellStyle} 
              title={tooltipMessage}
            >
              {cellValue ? Number(cellValue).toLocaleString() : ""}
            </div>
          );

        case "LIST":
          return (
            <div 
              className={readOnlyClass} 
              style={cellStyle}
              title={tooltipMessage}
            >
              {String(cellValue ?? "")}
            </div>
          );

        case "STRING":
        default:
          return (
            <div 
              className={readOnlyClass} 
              style={cellStyle}
              title={tooltipMessage}
            >
              {String(cellValue ?? "")}
            </div>
          );
      }
    },
  }));

  columns.push(...baseColumns);
  // (4) 액션 칼럼 - update 버튼 예시
  const actionColumn: ColumnDef<TData> = {
    id: "update",
    header: "",
    cell: ({ row }) => (
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button
            aria-label="Open menu"
            variant="ghost"
            className="flex size-8 p-0 data-[state=open]:bg-muted"
          >
            <Ellipsis className="size-4" aria-hidden="true" />
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end" className="w-40">
          <DropdownMenuItem
            onSelect={() => {
              setRowAction({ row, type: "update" });
            }}
          >
            Edit
          </DropdownMenuItem>
          <DropdownMenuItem
            onSelect={() => {
              if(tempCount > 0){
                const { original } = row;
                setReportData([original]);
              } else {
                toast.error("업로드된 Template File이 없습니다.");
              }
            }}
          >
            Create Document
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
    ),
    minSize: 50,
    enablePinning: true,
  };

  columns.push(actionColumn);

  // (5) 최종 반환
  return columns;
}