'use client';

import { useState, useMemo, useEffect, useCallback } from 'react';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { Building2 } from 'lucide-react';
import { DepartmentStats } from './DepartmentStats';
import { DepartmentToolbar } from './DepartmentToolbar';
import { DepartmentTree } from './DepartmentTree';
import { DepartmentDialog } from './DepartmentDialog';
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
import type { Department, DepartmentFormData, StatusFilter } from './types';
import { countAllDepartments, getAllDepartmentIds, findDepartmentById, filterDepartmentTree } from './types';
import {
  getDepartmentTree,
  createDepartment,
  updateDepartment,
  deleteDepartment,
  deleteDepartmentsMany,
  type DepartmentRecord,
} from './actions';
import { isNextRedirectError } from '@/lib/utils/redirect-error';

/**
 * API 응답을 로컬 Department 타입으로 변환
 */
function convertApiToLocal(record: DepartmentRecord): Department {
  return {
    id: record.id,
    code: record.code,
    name: record.name,
    description: record.description,
    parentId: record.parentId,
    isActive: record.isActive,
    sortOrder: record.sortOrder,
    depth: record.depth,
    children: record.children ? record.children.map(convertApiToLocal) : [],
  };
}

export function DepartmentManagement() {
  // 부서 데이터 상태
  const [departments, setDepartments] = useState<Department[]>([]);

  // 로딩/처리 상태
  const [, setIsLoading] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);

  // 선택 상태
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());

  // 펼침 상태 (기본: 최상위만 펼침)
  const [expandedIds, setExpandedIds] = useState<Set<number>>(new Set());

  // 검색어
  const [searchQuery, setSearchQuery] = useState('');

  // 상태 필터
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');

  /**
   * 부서 트리 조회 API
   */
  const fetchDepartments = useCallback(async () => {
    setIsLoading(true);
    try {
      const result = await getDepartmentTree();
      if (result.success && result.data) {
        const converted = result.data.map(convertApiToLocal);
        setDepartments(converted);
        // 최상위 부서 펼침
        if (converted.length > 0) {
          setExpandedIds(new Set([converted[0].id]));
        }
      } else {
        console.error('[DepartmentManagement] fetchDepartments error:', result.error);
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('[DepartmentManagement] fetchDepartments error:', error);
    } finally {
      setIsLoading(false);
    }
  }, []);

  // 초기 데이터 로드
  useEffect(() => {
    fetchDepartments();
  }, [fetchDepartments]);

  // 다이얼로그 상태
  const [dialogOpen, setDialogOpen] = useState(false);
  const [dialogMode, setDialogMode] = useState<'add' | 'edit'>('add');
  const [selectedDepartment, setSelectedDepartment] = useState<Department | undefined>();
  const [parentDepartment, setParentDepartment] = useState<Department | undefined>();

  // 삭제 확인 다이얼로그
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [departmentToDelete, setDepartmentToDelete] = useState<Department | null>(null);
  const [isBulkDelete, setIsBulkDelete] = useState(false);

  // 필터링된 부서 트리
  const filteredDepartments = useMemo(
    () => filterDepartmentTree(departments, searchQuery, statusFilter),
    [departments, searchQuery, statusFilter],
  );

  // 전체 부서 수 (필터 전)
  const totalCount = useMemo(() => countAllDepartments(departments), [departments]);

  // 필터된 부서 수
  const filteredCount = useMemo(() => countAllDepartments(filteredDepartments), [filteredDepartments]);

  // 필터된 부서 ID
  const filteredAllIds = useMemo(() => getAllDepartmentIds(filteredDepartments), [filteredDepartments]);

  // 펼침/접힘 토글
  const handleToggleExpand = (id: number) => {
    setExpandedIds(prev => {
      const next = new Set(prev);
      if (next.has(id)) {
        next.delete(id);
      } else {
        next.add(id);
      }
      return next;
    });
  };

  // 선택 토글
  const handleToggleSelect = (id: number) => {
    setSelectedIds(prev => {
      const next = new Set(prev);
      if (next.has(id)) {
        next.delete(id);
      } else {
        next.add(id);
      }
      return next;
    });
  };

  // 전체 선택/해제 (필터된 부서 기준)
  const handleToggleSelectAll = () => {
    if (selectedIds.size === filteredAllIds.length) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(filteredAllIds));
    }
  };

  // 부서 추가 (행 버튼)
  const handleAdd = (parentId: number) => {
    const parent = findDepartmentById(departments, parentId);
    setParentDepartment(parent || undefined);
    setSelectedDepartment(undefined);
    setDialogMode('add');
    setDialogOpen(true);
  };

  // 부서 추가 (상단 버튼 - 선택된 부서의 하위에 일괄 추가)
  const handleBulkAdd = () => {
    if (selectedIds.size === 0) {
      // 선택된 부서가 없으면 최상위에 추가
      setParentDepartment(undefined);
    } else {
      // 선택된 첫 번째 부서를 부모로 설정
      const firstSelectedId = Array.from(selectedIds)[0];
      const parent = findDepartmentById(departments, firstSelectedId);
      setParentDepartment(parent || undefined);
    }
    setSelectedDepartment(undefined);
    setDialogMode('add');
    setDialogOpen(true);
  };

  // 부서 수정
  const handleEdit = (department: Department) => {
    setSelectedDepartment(department);
    setParentDepartment(undefined);
    setDialogMode('edit');
    setDialogOpen(true);
  };

  // 부서 삭제 (단일)
  const handleDelete = (department: Department) => {
    setDepartmentToDelete(department);
    setIsBulkDelete(false);
    setDeleteDialogOpen(true);
  };

  // 부서 삭제 (일괄)
  const handleBulkDelete = () => {
    if (selectedIds.size === 0) return;
    setDepartmentToDelete(null);
    setIsBulkDelete(true);
    setDeleteDialogOpen(true);
  };

  /**
   * 삭제 확인 핸들러 (API 연동)
   */
  const confirmDelete = useCallback(async () => {
    if (isProcessing) return;
    setIsProcessing(true);

    try {
      if (isBulkDelete) {
        // 일괄 삭제 API
        const ids = Array.from(selectedIds);
        const result = await deleteDepartmentsMany(ids);
        if (result.success) {
          await fetchDepartments();
          setSelectedIds(new Set());
        } else {
          console.error('[DepartmentManagement] 일괄 삭제 실패:', result.error);
        }
      } else if (departmentToDelete) {
        // 단일 삭제 API
        const result = await deleteDepartment(departmentToDelete.id);
        if (result.success) {
          await fetchDepartments();
          setSelectedIds((prev) => {
            const next = new Set(prev);
            next.delete(departmentToDelete.id);
            return next;
          });
        } else {
          console.error('[DepartmentManagement] 삭제 실패:', result.error);
        }
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('[DepartmentManagement] confirmDelete error:', error);
    } finally {
      setDeleteDialogOpen(false);
      setDepartmentToDelete(null);
      setIsProcessing(false);
    }
  }, [isBulkDelete, selectedIds, departmentToDelete, isProcessing, fetchDepartments]);

  /**
   * 부서 추가/수정 제출 핸들러 (API 연동)
   */
  const handleDialogSubmit = useCallback(async (formData: DepartmentFormData) => {
    if (isProcessing) return;
    setIsProcessing(true);

    try {
      if (dialogMode === 'add') {
        const result = await createDepartment({
          code: formData.code,
          name: formData.name,
          description: formData.description || undefined,
          sortOrder: formData.sortOrder,
          isActive: formData.isActive,
          parentId: parentDepartment?.id,
        });
        if (result.success) {
          await fetchDepartments();
        } else {
          console.error('[DepartmentManagement] 부서 생성 실패:', result.error);
        }
      } else if (dialogMode === 'edit' && selectedDepartment) {
        const result = await updateDepartment(selectedDepartment.id, {
          code: formData.code,
          name: formData.name,
          description: formData.description || undefined,
          sortOrder: formData.sortOrder,
          isActive: formData.isActive,
        });
        if (result.success) {
          await fetchDepartments();
        } else {
          console.error('[DepartmentManagement] 부서 수정 실패:', result.error);
        }
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('[DepartmentManagement] handleDialogSubmit error:', error);
    } finally {
      setDialogOpen(false);
      setIsProcessing(false);
    }
  }, [dialogMode, parentDepartment, selectedDepartment, isProcessing, fetchDepartments]);

  // 필터 활성 여부
  const isFiltered = searchQuery.trim() !== '' || statusFilter !== 'all';

  return (
    <PageLayout>
      <PageHeader
        title="부서관리"
        description="부서 정보를 관리합니다"
        icon={Building2}
      />

      <div className="space-y-4">
        {/* 전체 부서 카운트 */}
        <DepartmentStats totalCount={totalCount} />

        {/* 검색 + 필터 + 추가/삭제 버튼 */}
        <DepartmentToolbar
          totalCount={isFiltered ? filteredCount : totalCount}
          selectedCount={selectedIds.size}
          searchQuery={searchQuery}
          onSearchChange={setSearchQuery}
          statusFilter={statusFilter}
          onStatusFilterChange={setStatusFilter}
          onAdd={handleBulkAdd}
          onDelete={handleBulkDelete}
        />

        {/* 트리 테이블 */}
        <DepartmentTree
          departments={filteredDepartments}
          expandedIds={expandedIds}
          selectedIds={selectedIds}
          onToggleExpand={handleToggleExpand}
          onToggleSelect={handleToggleSelect}
          onToggleSelectAll={handleToggleSelectAll}
          onAdd={handleAdd}
          onEdit={handleEdit}
          onDelete={handleDelete}
        />
      </div>

      {/* 추가/수정 다이얼로그 */}
      <DepartmentDialog
        isOpen={dialogOpen}
        onOpenChange={setDialogOpen}
        mode={dialogMode}
        parentDepartment={parentDepartment}
        department={selectedDepartment}
        onSubmit={handleDialogSubmit}
      />

      {/* 삭제 확인 다이얼로그 */}
      <DeleteConfirmDialog
        open={deleteDialogOpen}
        onOpenChange={setDeleteDialogOpen}
        description={
          <>
            {isBulkDelete
              ? `선택한 부서 ${selectedIds.size}개를 삭제하시겠습니까?`
              : `"${departmentToDelete?.name}" 부서를 삭제하시겠습니까?`
            }
            <br />
            <span className="text-destructive">
              삭제된 부서의 인원은 회사(기본) 인원으로 변경됩니다.
            </span>
          </>
        }
        onConfirm={confirmDelete}
      />
    </PageLayout>
  );
}
