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 { Badge } from "@/components/ui/badge"; // Badge import 추가
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';
import { createFilterFn } from "@/components/client-data-table/table-filters";

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

/** 컬럼 타입 (필요에 따라 확장) */
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?: string;
  
  /** 템플릿에서 가져온 추가 정보 */
  hidden?: boolean;  // true이면 컬럼 숨김
  seq?: number;      // 정렬 순서
  head?: string;     // 헤더 텍스트 (우선순위 가장 높음)
}

/**
 * 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;
  // 새로 추가: templateData
  templateData?: any;
}

/**
 * 셀 주소(예: "A1", "B1", "AA1")에서 컬럼 순서를 추출하는 함수
 * A=0, B=1, C=2, ..., Z=25, AA=26, AB=27, ...
 */
function getColumnOrderFromCellAddress(cellAddress: string): number {
  if (!cellAddress || typeof cellAddress !== 'string') {
    return 999999; // 유효하지 않은 경우 맨 뒤로
  }

  // 셀 주소에서 알파벳 부분만 추출 (예: "A1" -> "A", "AA1" -> "AA")
  const match = cellAddress.match(/^([A-Z]+)/);
  if (!match) {
    return 999999;
  }

  const columnLetters = match[1];
  let result = 0;

  // 알파벳을 숫자로 변환 (26진법과 유사하지만 0이 없는 체계)
  for (let i = 0; i < columnLetters.length; i++) {
    const charCode = columnLetters.charCodeAt(i) - 65 + 1; // A=1, B=2, ..., Z=26
    result = result * 26 + charCode;
  }

  return result - 1; // 0부터 시작하도록 조정
}

/**
 * templateData에서 SPREAD_LIST의 컬럼 순서 정보를 추출하여 seq를 업데이트하는 함수
 */
function updateSeqFromTemplate(columnsJSON: DataTableColumnJSON[], templateData: any): DataTableColumnJSON[] {
  if (!templateData) {
    return columnsJSON; // templateData가 없으면 원본 그대로 반환
  }

  // templateData가 배열인지 단일 객체인지 확인
  let templates: any[];
  if (Array.isArray(templateData)) {
    templates = templateData;
  } else {
    templates = [templateData];
  }

  // SPREAD_LIST 타입의 템플릿 찾기
  const spreadListTemplate = templates.find(template => 
    template.TMPL_TYPE === 'SPREAD_LIST' && 
    template.SPR_LST_SETUP?.DATA_SHEETS
  );

  if (!spreadListTemplate) {
    return columnsJSON; // SPREAD_LIST 템플릿이 없으면 원본 그대로 반환
  }

  // MAP_CELL_ATT에서 ATT_ID와 IN 매핑 정보 추출
  const cellMappings = new Map<string, string>(); // key: ATT_ID, value: IN (셀 주소)

  spreadListTemplate.SPR_LST_SETUP.DATA_SHEETS.forEach((dataSheet: any) => {
    if (dataSheet.MAP_CELL_ATT) {
      dataSheet.MAP_CELL_ATT.forEach((mapping: any) => {
        if (mapping.ATT_ID && mapping.IN) {
          cellMappings.set(mapping.ATT_ID, mapping.IN);
        }
      });
    }
  });

  // columnsJSON을 복사하여 seq 값 업데이트
  const updatedColumns = columnsJSON.map(column => {
    const cellAddress = cellMappings.get(column.key);
    if (cellAddress) {
      // 셀 주소에서 컬럼 순서 추출
      const newSeq = getColumnOrderFromCellAddress(cellAddress);
      console.log(`🔄 Updating seq for ${column.key}: ${column.seq} -> ${newSeq} (from ${cellAddress})`);
      
      return {
        ...column,
        seq: newSeq
      };
    }
    return column; // 매핑이 없으면 원본 그대로
  });

  return updatedColumns;
}

/**
 * status 값에 따라 Badge variant를 결정하는 헬퍼 함수
 */
function getStatusBadgeVariant(status: string): "default" | "secondary" | "destructive" | "outline" {
  const statusStr = String(status).toLowerCase();
  
  switch (statusStr) {
    case 'NEW':
    case 'New':
    // case 'approved':
      return 'default'; // 초록색 계열
    case 'Updated or Modified':
    // case 'in progress':
    // case 'processing':
      return 'secondary'; // 노란색 계열
    case 'inactive':
    case 'rejected':
    case 'failed':
    case 'cancelled':
      return 'destructive'; // 빨간색 계열
    default:
      return 'outline'; // 기본 회색 계열
  }
}

/**
 * 헤더 텍스트를 결정하는 헬퍼 함수
 * displayLabel이 있으면 사용, 없으면 label 사용
 */
function getHeaderText(col: DataTableColumnJSON): string {
  if (col.displayLabel && col.displayLabel.trim()) {
    return col.displayLabel;
  }
  return col.label;
}

/**
 * 컬럼들을 seq 순서대로 배치하면서 연속된 같은 head를 가진 컬럼들을 그룹으로 묶는 함수
 */
function groupColumnsByHead(columns: DataTableColumnJSON[]): ColumnDef<any>[] {
  const result: ColumnDef<any>[] = [];
  let i = 0;

  while (i < columns.length) {
    const currentCol = columns[i];
    
    // head가 없거나 빈 문자열인 경우 일반 컬럼으로 처리
    if (!currentCol.head || !currentCol.head.trim()) {
      result.push(createColumnDef(currentCol, false));
      i++;
      continue;
    }

    // 같은 head를 가진 연속된 컬럼들을 찾기
    const groupHead = currentCol.head.trim();
    const groupColumns: DataTableColumnJSON[] = [currentCol];
    let j = i + 1;

    while (j < columns.length && columns[j].head && columns[j].head.trim() === groupHead) {
      groupColumns.push(columns[j]);
      j++;
    }

    // 그룹에 컬럼이 하나만 있으면 일반 컬럼으로 처리
    if (groupColumns.length === 1) {
      result.push(createColumnDef(currentCol, false));
    } else {
      // 그룹 컬럼 생성 (구분선 스타일 적용)
      const groupColumn: ColumnDef<any> = {
        id: `group-${groupHead.replace(/\s+/g, '-')}`,
        header: groupHead,
        columns: groupColumns.map(col => createColumnDef(col, true)),
        meta: {
          isGroupColumn: true,
          groupBorders: true, // 그룹 구분선 표시 플래그
        }
      };
      result.push(groupColumn);
    }

    i = j; // 다음 그룹으로 이동
  }

  return result;
}

/**
 * 개별 컬럼 정의를 생성하는 헬퍼 함수
 */
function createColumnDef(col: DataTableColumnJSON, isInGroup: boolean = false): ColumnDef<any> {
  return {
    accessorKey: col.key,
    header: ({ column }) => (
      <ClientDataTableColumnHeaderSimple
        column={column}
        title={getHeaderText(col)}
      />
    ),

    filterFn: col.type === 'NUMBER' ? createFilterFn("number") : col.type === 'LIST' ? createFilterFn("multi-select"):createFilterFn("text"), 

    meta: {
      excelHeader: col.label,
      minWidth: 80,
      paddingFactor: 1.2,
      maxWidth: col.key === "TAG_NO" ? 120 : 150,
      isReadOnly: col.shi === true,
      isInGroup, // 그룹 내 컬럼인지 표시
      groupBorders: isInGroup, // 그룹 구분선 표시 플래그
    },
    
    cell: ({ row }) => {
      const cellValue = row.getValue(col.key);
      
      // SHI 필드만 읽기 전용으로 처리
      const isReadOnly = col.shi === true;
      
      // 그룹 구분선 스타일 클래스 추가
      const groupBorderClass = isInGroup ? "group-column-border" : "";
      const readOnlyClass = isReadOnly ? "read-only-cell" : "";
      const combinedClass = [groupBorderClass, readOnlyClass].filter(Boolean).join(" ");
      
      const cellStyle = {
        ...(isReadOnly && { backgroundColor: '#f5f5f5', color: '#666', cursor: 'not-allowed' }),
        ...(isInGroup && { 
          borderLeft: '2px solid #e2e8f0',
          borderRight: '2px solid #e2e8f0',
          position: 'relative' as const
        })
      };

      // 툴팁 메시지 설정 (SHI 필드만)
      const tooltipMessage = isReadOnly ? "SHI 전용 필드입니다" : "";

      // status 컬럼인 경우 Badge 적용
      if (col.key === "status") {
        const statusValue = String(cellValue ?? "");
        const badgeVariant = getStatusBadgeVariant(statusValue);
        
        return (
          <div 
            className={combinedClass}
            style={cellStyle}
            title={tooltipMessage}
          >
            <Badge variant={badgeVariant}>
              {statusValue}
            </Badge>
          </div>
        );
      }

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

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

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

/**
 * getColumns 함수
 * 1) columnsJSON 배열을 필터링 (hidden이 true가 아닌 것들만)
 * 2) seq에 따라 정렬
 * 3) seq 순서를 유지하면서 연속된 같은 head를 가진 컬럼들을 그룹으로 묶기
 * 4) 체크박스 컬럼 추가
 * 5) 마지막에 "Action" 칼럼 추가
 */
export function getColumns<TData extends object>({
  columnsJSON,
  setRowAction,
  setReportData,
  tempCount,
  selectedRows = {},
  onRowSelectionChange,
  templateData, // 새로 추가된 매개변수
}: GetColumnsProps<TData>): ColumnDef<TData>[] {
  const columns: ColumnDef<TData>[] = [];

  // (0) templateData에서 SPREAD_LIST인 경우 seq 값 업데이트
  const processedColumnsJSON = updateSeqFromTemplate(columnsJSON, templateData);

  // (1) 컬럼 필터링 및 정렬
  const visibleColumns = processedColumnsJSON
    .filter(col => col.hidden !== true) // hidden이 true가 아닌 것들만
    .sort((a, b) => {
      // seq가 없는 경우 999999로 처리하여 맨 뒤로 보냄
      const seqA = a.seq !== undefined ? a.seq : 999999;
      const seqB = b.seq !== undefined ? b.seq : 999999;
      return seqA - seqB;
    });

  console.log('📊 Final column order after template processing:', 
    visibleColumns.map(c => `${c.key}(seq:${c.seq})`));

  // (2) 체크박스 컬럼 (항상 표시)
  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,
    enablePinning: true,
    size: 40,
  };
  columns.push(selectColumn);

  // (3) 기본 컬럼들 (seq 순서를 유지하면서 head에 따라 그룹핑 처리)
  const groupedColumns = groupColumnsByHead(visibleColumns);
  columns.push(...groupedColumns);
  
  // (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>
          <DropdownMenuSeparator />
          <DropdownMenuItem
            onSelect={() => {
              setRowAction({ row, type: "delete" });
            }}
            className="text-red-600 focus:text-red-600"
          >
            Delete
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
    ),
    size: 40,
    enablePinning: true,
  };

  columns.push(actionColumn);

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