"use client"

import * as React from "react"
import { type DataTableRowAction } from "@/types/table"
import { type ColumnDef } from "@tanstack/react-table"
import { Ellipsis, Paperclip, FileText } from "lucide-react"
import { toast } from "sonner"

import { formatDate, formatDateTime } from "@/lib/utils"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuShortcut,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
import { ProjectGtcView } from "@/db/schema"

interface GetColumnsProps {
  setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<ProjectGtcView> | null>>
}

/**
 * 파일 다운로드 함수
 */
const handleFileDownload = async (projectId: number, fileName: string) => {
  try {
    // API를 통해 파일 다운로드
    const response = await fetch(`/api/project-gtc?action=download&projectId=${projectId}`, {
      method: 'GET',
    });

    if (!response.ok) {
      throw new Error('파일 다운로드에 실패했습니다.');
    }

    // 파일 blob 생성
    const blob = await response.blob();
    
    // 다운로드 링크 생성
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = fileName;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    
    // 메모리 정리
    window.URL.revokeObjectURL(url);
    
    toast.success("파일 다운로드를 시작합니다.");
  } catch (error) {
    console.error("파일 다운로드 오류:", error);
    toast.error("파일 다운로드 중 오류가 발생했습니다.");
  }
};

/**
 * tanstack table 컬럼 정의 (중첩 헤더 버전)
 */
export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<ProjectGtcView>[] {
  // ----------------------------------------------------------------
  // 1) select 컬럼 (체크박스)
  // ----------------------------------------------------------------
  const selectColumn: ColumnDef<ProjectGtcView> = {
    id: "select",
    header: ({ table }) => (
      <Checkbox
        checked={
          table.getIsAllPageRowsSelected() ||
          (table.getIsSomePageRowsSelected() && "indeterminate")
        }
        onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
        aria-label="Select all"
        className="translate-y-0.5"
      />
    ),
    cell: ({ row }) => (
      <Checkbox
        checked={row.getIsSelected()}
        onCheckedChange={(value) => row.toggleSelected(!!value)}
        aria-label="Select row"
        className="translate-y-0.5"
      />
    ),
    maxSize: 30,
    enableSorting: false,
    enableHiding: false,
  }

  // ----------------------------------------------------------------
  // 2) 파일 다운로드 컬럼 (아이콘)
  // ----------------------------------------------------------------
  const downloadColumn: ColumnDef<ProjectGtcView> = {
    id: "download",
    header: "",
    cell: ({ row }) => {
      const project = row.original;
      
      if (!project.filePath || !project.originalFileName) {
        return null;
      }
      
      return (
        <Button
          variant="ghost"
          size="icon"
          onClick={() => handleFileDownload(project.id, project.originalFileName!)}
          title={`${project.originalFileName} 다운로드`}
          className="hover:bg-muted"
        >
          <Paperclip className="h-4 w-4" />
          <span className="sr-only">다운로드</span>
        </Button>
      );
    },
    maxSize: 30,
    enableSorting: false,
  }

  // ----------------------------------------------------------------
  // 3) actions 컬럼 (Dropdown 메뉴)
  // ----------------------------------------------------------------
  const actionsColumn: ColumnDef<ProjectGtcView> = {
    id: "actions",
    enableHiding: false,
    cell: function Cell({ row }) {
      return (
        <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({ type: "upload", row })}
            >
              Edit
            </DropdownMenuItem>

            <DropdownMenuSeparator />
            <DropdownMenuItem
              onSelect={() => setRowAction({ type: "delete", row })}
            >
              Delete
              <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      )
    },
    maxSize: 30,
  }

  // ----------------------------------------------------------------
  // 4) 일반 컬럼들을 "그룹"별로 묶어 중첩 columns 생성
  // ----------------------------------------------------------------
  // 4-1) groupMap: { [groupName]: ColumnDef<ProjectGtcView>[] }
  const groupMap: Record<string, ColumnDef<ProjectGtcView>[]> = {}

  // 프로젝트 정보 그룹
  groupMap["기본 정보"] = [
    {
      accessorKey: "code",
      header: ({ column }) => (
        <DataTableColumnHeaderSimple column={column} title="프로젝트 코드" />
      ),
      cell: ({ row }) => {
        return (
          <div className="flex space-x-2">
            <span className="max-w-[500px] truncate font-medium">
              {row.getValue("code")}
            </span>
          </div>
        )
      },
      filterFn: (row, id, value) => {
        return value.includes(row.getValue(id))
      },
      minSize: 120,
    },
    {
      accessorKey: "name",
      header: ({ column }) => (
        <DataTableColumnHeaderSimple column={column} title="프로젝트명" />
      ),
      cell: ({ row }) => {
        return (
          <div className="flex space-x-2">
            <span className="max-w-[500px] truncate">
              {row.getValue("name")}
            </span>
          </div>
        )
      },
      filterFn: (row, id, value) => {
        return value.includes(row.getValue(id))
      },
      minSize: 200,
    },
    {
      accessorKey: "type",
      header: ({ column }) => (
        <DataTableColumnHeaderSimple column={column} title="프로젝트 타입" />
      ),
      cell: ({ row }) => {
        const type = row.getValue("type") as string
        return (
          <div className="flex w-[100px] items-center">
            <Badge variant="secondary">
              {type}
            </Badge>
          </div>
        )
      },
      filterFn: (row, id, value) => {
        return value.includes(row.getValue(id))
      },
      minSize: 100,
    },
  ]

  // 파일 정보 그룹
  groupMap["파일 정보"] = [
    {
      accessorKey: "originalFileName",
      header: ({ column }) => (
        <DataTableColumnHeaderSimple column={column} title="GTC 파일" />
      ),
      cell: ({ row }) => {
        const fileName = row.getValue("originalFileName") as string | null
        const filePath = row.original.filePath

        if (!fileName) {
          return (
            <div className="flex items-center text-muted-foreground">
              <FileText className="mr-2 h-4 w-4" />
              <span>파일 없음</span>
            </div>
          )
        }

        return (
          <div className="flex items-center space-x-2">
            <FileText className="h-4 w-4" />
            <div className="flex flex-col">
              {filePath ? (
                <button
                  onClick={async (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    try {
                      // API를 통해 파일 다운로드
                      const response = await fetch(`/api/project-gtc?action=download&projectId=${row.original.id}`, {
                        method: 'GET',
                      });

                      if (!response.ok) {
                        throw new Error('파일을 열 수 없습니다.');
                      }

                      // 파일 blob 생성
                      const blob = await response.blob();
                      const url = window.URL.createObjectURL(blob);
                      window.open(url, '_blank');
                    } catch (error) {
                      console.error("파일 미리보기 오류:", error);
                      toast.error("파일을 열 수 없습니다.");
                    }
                  }}
                  className="font-medium text-left hover:underline cursor-pointer text-blue-600 hover:text-blue-800 transition-colors"
                  title="클릭하여 파일 열기"
                >
                  {fileName}
                </button>
              ) : (
                <span className="font-medium">{fileName}</span>
              )}
            </div>
          </div>
        )
      },
      minSize: 200,
    },
  ]

  // 날짜 정보 그룹
  groupMap["날짜 정보"] = [
    {
      accessorKey: "gtcCreatedAt",
      header: ({ column }) => (
        <DataTableColumnHeaderSimple column={column} title="GTC 등록일" />
      ),
      cell: ({ row }) => {
        const date = row.getValue("gtcCreatedAt") as Date | null
        if (!date) {
          return <span className="text-muted-foreground">-</span>
        }
        return (
          <div className="flex items-center">
            <span>
              {formatDateTime(new Date(date))}
            </span>
          </div>
        )
      },
      minSize: 150,
    },
    {
      accessorKey: "projectCreatedAt",
      header: ({ column }) => (
        <DataTableColumnHeaderSimple column={column} title="프로젝트 생성일" />
      ),
      cell: ({ row }) => {
        const date = row.getValue("projectCreatedAt") as Date
        return (
          <div className="flex items-center">
            <span>
              {formatDate(new Date(date))}
            </span>
          </div>
        )
      },
      minSize: 120,
    },
  ]

  // ----------------------------------------------------------------
  // 4-2) groupMap에서 실제 상위 컬럼(그룹)을 만들기
  // ----------------------------------------------------------------
  const nestedColumns: ColumnDef<ProjectGtcView>[] = []

  // 순서를 고정하고 싶다면 group 순서를 미리 정의하거나 sort해야 함
  Object.entries(groupMap).forEach(([groupName, colDefs]) => {
    // 상위 컬럼
    nestedColumns.push({
      id: groupName,
      header: groupName, // "프로젝트 정보", "파일 정보", "날짜 정보" 등
      columns: colDefs,
    })
  })

  // ----------------------------------------------------------------
  // 5) 최종 컬럼 배열: select, download, nestedColumns, actions
  // ----------------------------------------------------------------
  return [
    selectColumn,
    downloadColumn, // 다운로드 컬럼 추가
    ...nestedColumns,
    actionsColumn,
  ]
} 