"use client"

import * as React from "react"
import { type Table } from "@tanstack/react-table"
import { useQueryState, parseAsArrayOf, parseAsString } from "nuqs"
import { Layers, Check, ChevronsUpDown, GripVertical, XCircle } from "lucide-react"

import { toSentenceCase, cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import {
  Popover,
  PopoverTrigger,
  PopoverContent,
} from "@/components/ui/popover"
import {
  Command,
  CommandList,
  CommandGroup,
  CommandItem,
  CommandInput,
  CommandEmpty,
} from "@/components/ui/command"
import {
  Sortable,
  SortableItem,
  SortableDragHandle,
} from "@/components/ui/sortable"
import { useTranslation } from '@/i18n/client'
import { useParams, usePathname } from "next/navigation";

interface DataTableGroupListProps<TData> {
  /** TanStack Table 인스턴스 (grouping을 이미 사용할 수 있어야 함) */
  table: Table<TData>
  /** 정렬과 동일하게 URL 쿼리에 grouping을 저장할 때 쓰는 debounce 시간 (ms) */
  debounceMs: number
  /** shallow 라우팅 여부 */
  shallow?: boolean
}

export function DataTableGroupList<TData>({
  table,
  debounceMs,
  shallow,
}: DataTableGroupListProps<TData>) {
  const id = React.useId()
  const params = useParams();
    const lng = params?.lng as string;
  const { t } = useTranslation(lng);

  // ------------------------------------------------------
  // 1) 초기 그룹핑 상태 + URL Query State 동기화
  // ------------------------------------------------------
  const initialGrouping = (table.initialState.grouping ?? []) as string[]

  // group 쿼리 파라미터를 string[]로 파싱
  // parseAsArrayOf(parseAsString, ',')를 이용
  const [grouping, setGrouping] = useQueryState(
    "group",
    parseAsArrayOf(parseAsString, ",")
      .withDefault(initialGrouping)
      .withOptions({
        clearOnDefault: true,
        shallow,
      })
  )

  // TanStack Table의 `table.setGrouping()`과 동기화
  // (정렬 모달 예시에서 setSorting()을 쓰듯이 여기서는 setGrouping() 호출)
  React.useEffect(() => {
    table.setGrouping(grouping)
  }, [grouping, table])

  // 이미 중복 추가된 그룹은 제거
  // (정렬 예시에서도 uniqueSorting 했듯이)
  const uniqueGrouping = React.useMemo(
    () => grouping.filter((id, i, self) => self.indexOf(id) === i),
    [grouping]
  )

  // ------------------------------------------------------
  // 2) 그룹핑 가능한 컬럼만 골라내기
  // ------------------------------------------------------
  const groupableColumns = React.useMemo(
    () =>
      table
        .getAllColumns()
        .filter((col) => col.getCanGroup?.() !== false)
        .map((col) => ({
          id: col.id,
          label: toSentenceCase(col.id),
        })),
    [table]
  )

  // 이미 그룹핑 중인 컬럼 제외하고 "추가 가능"한 컬럼들
  const ungroupedColumns = React.useMemo(() => {
    return groupableColumns.filter(
      (column) => !grouping.includes(column.id)
    )
  }, [groupableColumns, grouping])



  // ------------------------------------------------------
  // 3) 그룹 배열을 업데이트하는 함수들
  // ------------------------------------------------------

  // 드래그/드롭으로 순서 변경
  function onGroupOrderChange(newGroups: string[]) {
    setGrouping(newGroups)
  }

  // "Add group" : 아직 그룹핑되지 않은 첫 번째 컬럼 추가
  function addGroup() {
    const firstAvailable = ungroupedColumns[0]
    if (!firstAvailable) return
    setGrouping([...grouping, firstAvailable.id])
  }

  // 특정 아이템(그룹 컬럼 id) 제거
  function removeGroup(id: string) {
    setGrouping((prev) => prev.filter((g) => g !== id))
  }

  // 전체 그룹핑 초기화
  function resetGrouping() {
    setGrouping([])
  }

  // ------------------------------------------------------
  // 4) 렌더링
  // ------------------------------------------------------

  return (
    <Sortable
      // sorting 예시처럼 Sortable 컨테이너로 감싸기
      // 여기선 "grouping"을 바로 value로 넘길 수 없고,
      // Sortable는 { id: UniqueIdentifier }[] 형태를 요구하므로 변환 필요
      value={grouping.map((id) => ({ id }))}
      onValueChange={(items) => {
        // 드래그 완료 시 string[] 형태로 되돌림
        onGroupOrderChange(items.map((i) => i.id))
      }}
      // overlay : 드래그 중 placeholder UI
      overlay={
        <div className="flex items-center gap-2">
          <div className="h-8 w-[11.25rem] rounded-sm bg-primary/10" />
          <div className="h-8 w-24 rounded-sm bg-primary/10" />
          <div className="size-8 shrink-0 rounded-sm bg-primary/10" />
        </div>
      }
    >
      <Popover>
        <PopoverTrigger asChild>
          <Button
            variant="outline"
            size="sm"
            className="gap-2"
            aria-label="Open grouping"
            aria-controls={`${id}-group-dialog`}
          >
            <Layers className="size-3" aria-hidden="true" />
            <span className="hidden sm:inline">{t("tableToolBar.group")}</span>
            {uniqueGrouping.length > 0 && (
              <Badge
                variant="secondary"
                className="h-[1.14rem] rounded-[0.2rem] px-[0.32rem] font-mono text-[0.65rem] font-normal"
              >
                {uniqueGrouping.length}
              </Badge>
            )}
          </Button>
        </PopoverTrigger>

        <PopoverContent
          id={`${id}-group-dialog`}
          align="start"
          collisionPadding={16}
          className={cn(
            "flex w-[calc(100vw-theme(spacing.20))] min-w-72 max-w-[25rem] origin-[var(--radix-popover-content-transform-origin)] flex-col p-4 sm:w-[25rem]",
            grouping.length > 0 ? "gap-3.5" : "gap-2"
          )}
        >
          {uniqueGrouping.length > 0 ? (
            <>
              <h4 className="font-medium leading-none">Group by</h4>
              <p className="text-sm text-muted-foreground">
                그룹핑은 불러온 데이터에 한해서 그룹핑이 됩니다.
              </p>
            </>

          ) : (
            <div className="flex flex-col gap-1">
              <h4 className="font-medium leading-none">No grouping applied</h4>
              <p className="text-sm text-muted-foreground">
                Add grouping to organize your results.
              </p>
            </div>
          )}

          {/* 그룹 목록 */}
          <div className="flex max-h-40 flex-col gap-2 overflow-y-auto p-0.5">
            <div className="flex w-full flex-col gap-2">
              {uniqueGrouping.map((colId) => {
                // SortableItem에 key로 colId
                return (
                  <SortableItem key={colId} value={colId} asChild>
                    <div className="flex items-center gap-2">
                      <Popover modal>
                        <PopoverTrigger asChild>
                          <Button
                            variant="outline"
                            size="sm"
                            role="combobox"
                            className="h-8 w-44 justify-between gap-2 rounded focus:outline-none focus:ring-1 focus:ring-ring"
                            aria-label={`Select column for group ${colId}`}
                          >
                            <span className="truncate">
                              {toSentenceCase(colId)}
                            </span>
                            <div className="ml-auto flex items-center gap-1">
                              <ChevronsUpDown
                                className="size-4 shrink-0 opacity-50"
                                aria-hidden="true"
                              />
                            </div>
                          </Button>
                        </PopoverTrigger>
                        <PopoverContent
                          className="w-[var(--radix-popover-trigger-width)] p-0"
                        >
                          <Command>
                            <CommandInput placeholder="Search columns..." />
                            <CommandList>
                              <CommandEmpty>No columns found.</CommandEmpty>
                              <CommandGroup>
                                {ungroupedColumns.map((column) => (
                                  <CommandItem
                                    key={column.id}
                                    value={column.id}
                                    onSelect={(value) => {
                                      // colId -> 새로 선택한 value로 교체
                                      setGrouping((prev) =>
                                        prev.map((g) =>
                                          g === colId ? value : g
                                        )
                                      )
                                    }}
                                  >
                                    <span className="mr-1.5 truncate">
                                      {column.label}
                                    </span>
                                    <Check
                                      className={cn(
                                        "ml-auto size-4 shrink-0",
                                        column.id === colId
                                          ? "opacity-100"
                                          : "opacity-0"
                                      )}
                                      aria-hidden="true"
                                    />
                                  </CommandItem>
                                ))}
                              </CommandGroup>
                            </CommandList>
                          </Command>
                        </PopoverContent>
                      </Popover>

                      {/* remove group */}
                      <Button
                        variant="outline"
                        size="icon"
                        aria-label={`Remove group ${colId}`}
                        className="size-8 shrink-0 rounded"
                        onClick={() => removeGroup(colId)}
                      >
                        <XCircle className="size-3.5" aria-hidden="true" />
                      </Button>

                      {/* drag handle */}
                      <SortableDragHandle
                        variant="outline"
                        size="icon"
                        className="size-8 shrink-0 rounded"
                      >
                        <GripVertical className="size-3.5" aria-hidden="true" />
                      </SortableDragHandle>
                    </div>
                  </SortableItem>
                )
              })}
            </div>
          </div>

          <div className="flex w-full items-center gap-2">
            {/* 새 그룹 추가 */}
            <Button
              size="sm"
              className="h-[1.85rem] rounded"
              onClick={addGroup}
              disabled={grouping.length >= groupableColumns.length}
            >
              Add group
            </Button>
            {grouping.length > 0 && (
              <Button
                size="sm"
                variant="outline"
                className="rounded"
                onClick={resetGrouping}
              >
                Reset grouping
              </Button>
            )}
          </div>
        </PopoverContent>
      </Popover>
    </Sortable>
  )
}