'use client';

/**
 * 담당자 선택 모달
 *
 * 부서별로 그룹화된 담당자를 다중 선택할 수 있는 모달
 * API 연동: GET /api/v1/departments/tree?with_users=1
 */

import { useState, useEffect, useMemo } from 'react';
import { Check, ChevronDown, ChevronRight } from 'lucide-react';
import { ContentSkeleton } from '@/components/ui/skeleton';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import {
  Dialog,
  DialogContent,
  DialogTitle,
} from '@/components/ui/dialog';
import { VisuallyHidden } from '@radix-ui/react-visually-hidden';
import { getDepartmentsWithUsers, type DepartmentWithUsers, type DepartmentUser } from './actions';

interface AssigneeSelectModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  selectedIds: string[];
  onSelect: (ids: string[], names: string[]) => void;
}

export function AssigneeSelectModal({
  open,
  onOpenChange,
  selectedIds,
  onSelect,
}: AssigneeSelectModalProps) {
  const [departments, setDepartments] = useState<DepartmentWithUsers[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [localSelected, setLocalSelected] = useState<Set<string>>(new Set(selectedIds));
  const [expandedDepts, setExpandedDepts] = useState<Set<number>>(new Set());

  // 부서 데이터 로드
  useEffect(() => {
    if (open) {
      loadDepartments();
      setLocalSelected(new Set(selectedIds));
    }
  }, [open, selectedIds]);

  const loadDepartments = async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await getDepartmentsWithUsers();
      if (result.success) {
        setDepartments(result.data);
        // 모든 부서 펼치기
        const allDeptIds = collectAllDeptIds(result.data);
        setExpandedDepts(new Set(allDeptIds));
      } else {
        setError(result.error || '부서 목록을 불러올 수 없습니다.');
      }
    } catch {
      setError('서버 오류가 발생했습니다.');
    } finally {
      setLoading(false);
    }
  };

  // 모든 부서 ID 수집 (재귀)
  const collectAllDeptIds = (depts: DepartmentWithUsers[]): number[] => {
    const ids: number[] = [];
    depts.forEach((d) => {
      ids.push(d.id);
      if (d.children.length > 0) {
        ids.push(...collectAllDeptIds(d.children));
      }
    });
    return ids;
  };

  // 전체 사용자 맵 (id -> user)
  const userMap = useMemo(() => {
    const map = new Map<string, DepartmentUser & { deptName: string }>();
    const collectUsers = (depts: DepartmentWithUsers[]) => {
      depts.forEach((dept) => {
        dept.users.forEach((user) => {
          map.set(String(user.id), { ...user, deptName: dept.name });
        });
        if (dept.children.length > 0) {
          collectUsers(dept.children);
        }
      });
    };
    collectUsers(departments);
    return map;
  }, [departments]);

  // 부서의 모든 사용자 ID 수집 (하위 부서 포함)
  const getAllUserIdsInDept = (dept: DepartmentWithUsers): string[] => {
    const ids = dept.users.map((u) => String(u.id));
    dept.children.forEach((child) => {
      ids.push(...getAllUserIdsInDept(child));
    });
    return ids;
  };

  // 부서 전체 선택 여부 확인
  const isDeptFullySelected = (dept: DepartmentWithUsers): boolean => {
    const allIds = getAllUserIdsInDept(dept);
    if (allIds.length === 0) return false;
    return allIds.every((id) => localSelected.has(id));
  };

  // 부서 부분 선택 여부 확인
  const isDeptPartiallySelected = (dept: DepartmentWithUsers): boolean => {
    const allIds = getAllUserIdsInDept(dept);
    if (allIds.length === 0) return false;
    const selectedCount = allIds.filter((id) => localSelected.has(id)).length;
    return selectedCount > 0 && selectedCount < allIds.length;
  };

  // 개별 담당자 토글
  const toggleUser = (userId: string) => {
    const newSelected = new Set(localSelected);
    if (newSelected.has(userId)) {
      newSelected.delete(userId);
    } else {
      newSelected.add(userId);
    }
    setLocalSelected(newSelected);
  };

  // 부서 전체 토글
  const toggleDept = (dept: DepartmentWithUsers) => {
    const newSelected = new Set(localSelected);
    const allIds = getAllUserIdsInDept(dept);
    const isFullySelected = isDeptFullySelected(dept);

    if (isFullySelected) {
      allIds.forEach((id) => newSelected.delete(id));
    } else {
      allIds.forEach((id) => newSelected.add(id));
    }
    setLocalSelected(newSelected);
  };

  // 부서 펼침/접기 토글
  const toggleExpand = (deptId: number) => {
    const newExpanded = new Set(expandedDepts);
    if (newExpanded.has(deptId)) {
      newExpanded.delete(deptId);
    } else {
      newExpanded.add(deptId);
    }
    setExpandedDepts(newExpanded);
  };

  // 선택 완료
  const handleConfirm = () => {
    const ids = Array.from(localSelected);
    const names = ids.map((id) => userMap.get(id)?.name || '').filter(Boolean);
    onSelect(ids, names);
    onOpenChange(false);
  };

  // 부서 렌더링 (재귀)
  const renderDepartment = (dept: DepartmentWithUsers, depth: number = 0) => {
    const hasChildren = dept.children.length > 0;
    const hasUsers = dept.users.length > 0;
    const isExpanded = expandedDepts.has(dept.id);
    const totalUsers = getAllUserIdsInDept(dept).length;

    if (totalUsers === 0) return null;

    return (
      <div key={dept.id}>
        {/* 부서 헤더 */}
        <div
          className="flex items-center justify-between px-6 py-3 border-b bg-white hover:bg-gray-50"
          style={{ paddingLeft: `${24 + depth * 16}px` }}
        >
          <div className="flex items-center gap-2">
            {/* 펼침/접기 버튼 */}
            {(hasChildren || hasUsers) && (
              <button
                type="button"
                onClick={() => toggleExpand(dept.id)}
                className="p-0.5 hover:bg-gray-200 rounded"
              >
                {isExpanded ? (
                  <ChevronDown className="w-4 h-4 text-gray-500" />
                ) : (
                  <ChevronRight className="w-4 h-4 text-gray-500" />
                )}
              </button>
            )}

            <Checkbox
              id={`dept-${dept.id}`}
              checked={isDeptFullySelected(dept)}
              className="h-5 w-5 rounded border-2"
              data-state={
                isDeptPartiallySelected(dept)
                  ? 'indeterminate'
                  : isDeptFullySelected(dept)
                    ? 'checked'
                    : 'unchecked'
              }
              onCheckedChange={() => toggleDept(dept)}
            />
            <label
              htmlFor={`dept-${dept.id}`}
              className="flex items-center gap-2 cursor-pointer"
            >
              <span className="text-muted-foreground">👥</span>
              <span className="font-medium">{dept.name}</span>
              <span className="text-sm text-muted-foreground">({totalUsers}명)</span>
            </label>
          </div>
          <button
            type="button"
            onClick={() => toggleDept(dept)}
            className="text-xs text-muted-foreground hover:text-foreground"
          >
            전체선택
          </button>
        </div>

        {/* 펼쳐진 경우 사용자 및 하위 부서 표시 */}
        {isExpanded && (
          <>
            {/* 부서 소속 사용자 */}
            {dept.users.map((user) => (
              <div
                key={user.id}
                className="flex items-center gap-3 px-6 py-3 border-b bg-gray-50/50"
                style={{ paddingLeft: `${48 + depth * 16}px` }}
              >
                <Checkbox
                  id={`user-${user.id}`}
                  checked={localSelected.has(String(user.id))}
                  className="h-5 w-5 rounded border-2"
                  onCheckedChange={() => toggleUser(String(user.id))}
                />
                <label
                  htmlFor={`user-${user.id}`}
                  className="flex items-center gap-2 cursor-pointer flex-1"
                >
                  <span className="text-muted-foreground">👤</span>
                  <span>{user.name}</span>
                  <span className="text-xs text-muted-foreground">{user.email}</span>
                </label>
              </div>
            ))}

            {/* 하위 부서 (재귀) */}
            {dept.children.map((child) => renderDepartment(child, depth + 1))}
          </>
        )}
      </div>
    );
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-lg p-0 gap-0">
        <VisuallyHidden>
          <DialogTitle>담당자 선택</DialogTitle>
        </VisuallyHidden>

        {/* 헤더 */}
        <div className="px-6 py-4 border-b">
          <h2 className="text-lg font-semibold">담당자 선택</h2>
        </div>

        {/* 설명 텍스트 */}
        <p className="text-sm text-muted-foreground px-6 py-3 border-b bg-gray-50">
          부서 전체 또는 개별 작업자를 선택할 수 있습니다
        </p>

        {/* 컨텐츠 영역 */}
        <div className="max-h-[400px] overflow-y-auto">
          {loading ? (
            <ContentSkeleton type="list" rows={6} />
          ) : error ? (
            <div className="flex flex-col items-center justify-center py-12 text-center">
              <p className="text-red-500 mb-2">{error}</p>
              <Button variant="outline" size="sm" onClick={loadDepartments}>
                다시 시도
              </Button>
            </div>
          ) : departments.length === 0 ? (
            <div className="flex items-center justify-center py-12 text-muted-foreground">
              등록된 부서가 없습니다
            </div>
          ) : (
            departments.map((dept) => renderDepartment(dept))
          )}
        </div>

        {/* 하단 버튼 */}
        <div className="px-6 py-4 border-t">
          <Button
            onClick={handleConfirm}
            className="w-full bg-black hover:bg-black/90"
            disabled={loading}
          >
            <Check className="w-4 h-4 mr-1.5" />
            선택 완료 ({localSelected.size}명)
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}
