"use client";

import { TreeSelect } from "antd";
import type { TreeSelectProps } from "antd";
import { useEffect, useMemo, useState } from "react";

import { fetchDepartments, type Department } from "@/lib/api/employees";
import { getPickerReadsBlockedMessage, isPickerReadsBlockedError } from "@/lib/api/errors";

export interface DepartmentDropdownProps {
  value?: string | string[];
  onChange?: (value: string | string[]) => void;
  mode?: "single" | "multiple";
  placeholder?: string;
  disabled?: boolean;
  allowClear?: boolean;
  id?: string;
  "aria-label"?: string;
  "aria-labelledby"?: string;
  "aria-describedby"?: string;
}

type TreeNode = NonNullable<TreeSelectProps["treeData"]>[number];

export default function DepartmentDropdown({
  value,
  onChange,
  mode = "single",
  placeholder = "Select department",
  disabled = false,
  allowClear = true,
  id,
  "aria-label": ariaLabel,
  "aria-labelledby": ariaLabelledBy,
  "aria-describedby": ariaDescribedBy,
}: DepartmentDropdownProps) {
  const [departments, setDepartments] = useState<Department[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    const loadDepartments = async () => {
      setLoading(true);
      setError(null);
      try {
        const data = await fetchDepartments();
        if (!cancelled) {
          setDepartments(data ?? []);
        }
      } catch (err) {
        if (!cancelled) {
          setDepartments([]);
          setError(isPickerReadsBlockedError(err) ? getPickerReadsBlockedMessage() : "Failed to load departments");
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    };
    loadDepartments();
    return () => {
      cancelled = true;
    };
  }, []);

  const treeData = useMemo(() => {
    const nodesById = new Map<string, TreeNode>();
    departments.forEach((dept) => {
      nodesById.set(dept.lark_department_id, {
        title: dept.name,
        value: dept.lark_department_id,
        key: dept.lark_department_id,
      });
    });

    const roots: TreeNode[] = [];
    departments.forEach((dept) => {
      const node = nodesById.get(dept.lark_department_id);
      if (!node) return;
      const parentId = dept.parent_id;
      if (parentId && nodesById.has(parentId)) {
        const parent = nodesById.get(parentId);
        if (parent) {
          parent.children = parent.children ? [...parent.children, node] : [node];
        }
      } else {
        roots.push(node);
      }
    });

    return roots;
  }, [departments]);

  const isMultiple = mode === "multiple";

  return (
    <TreeSelect
      value={value}
      treeData={treeData}
      placeholder={placeholder}
      allowClear={allowClear}
      multiple={isMultiple}
      treeCheckable={isMultiple}
      showCheckedStrategy={TreeSelect.SHOW_PARENT}
      showSearch
      treeDefaultExpandAll
      loading={loading}
      disabled={disabled}
      notFoundContent={loading ? "Loading..." : error ?? "No departments"}
      id={id}
      aria-label={ariaLabel}
      aria-labelledby={ariaLabelledBy}
      aria-describedby={ariaDescribedBy}
      onChange={(nextValue) => onChange?.(nextValue as string | string[])}
    />
  );
}
