import { useState, useEffect } from "react";
import axios from "axios";
import { Position } from "./usePositions";

interface ApiResponse<T> {
  success: boolean;
  data: T;
  message?: string;
}

export interface Department {
  id: string;
  name: string;
  positions: Position[];
  isExpanded?: boolean;
  parentDepartmentId?: string;
}

export const useDepartments = (unitId: string) => {
  const [departments, setDepartments] = useState<Department[]>([]);
  const [selectedDepartmentId, setSelectedDepartmentId] = useState<string>("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<Error | null>(null);

  // Fetch departments for a unit
  const fetchDepartments = async () => {
    if (!unitId) {
      setDepartments([]);
      setSelectedDepartmentId("");
      return;
    }

    setLoading(true);
    try {
      // In a real app, this would be an API call

      setTimeout(() => {
        // Mock departments for this unit
        const mockDepartments: Department[] = [
          {
            id: "dept1",
            name: "Directorate",
            positions: [],
            isExpanded: true,
          },
          {
            id: "dept2",
            name: "Development",
            positions: [],
            isExpanded: false,
          },
          {
            id: "dept3",
            name: "Operations",
            positions: [],
            isExpanded: false,
          },
        ];

        setDepartments(mockDepartments);
        if (mockDepartments.length > 0) {
          setSelectedDepartmentId(mockDepartments[0].id);
        } else {
          setSelectedDepartmentId("");
        }
        setLoading(false);
      }, 500);
    } catch (err) {
      setError(
        err instanceof Error ? err : new Error("Failed to fetch departments")
      );
      setLoading(false);
    }
  };

  // Create a new department
  const createDepartment = async (
    departmentData: Partial<Department>
  ): Promise<Department> => {
    if (!unitId) {
      throw new Error("No unit selected");
    }

    setLoading(true);
    try {
      // In a real app, this would be an API call
      // const response = await axios.post<ApiResponse<Department>>(
      //   `/api/units/${unitId}/departments`,
      //   departmentData
      // );
      // const newDepartment = response.data.data;

      // For now, simulate API response
      const newDepartment: Department = {
        id: `dept-${Date.now()}`,
        name: departmentData.name || "New Department",
        positions: [],
        isExpanded: false,
        parentDepartmentId: departmentData.parentDepartmentId,
      };

      setDepartments((prev) => [...prev, newDepartment]);
      setLoading(false);
      return newDepartment;
    } catch (err) {
      setError(
        err instanceof Error ? err : new Error("Failed to create department")
      );
      setLoading(false);
      throw err;
    }
  };

  // Update an existing department
  const updateDepartment = async (
    departmentId: string,
    updates: Partial<Department>
  ): Promise<Department> => {
    setLoading(true);
    try {
      // In a real app, this would be an API call
      // const response = await axios.put<ApiResponse<Department>>(
      //   `/api/departments/${departmentId}`,
      //   updates
      // );
      // const updatedDepartment = response.data.data;

      // For now, simulate API response
      const updatedDepartments = departments.map((department) =>
        department.id === departmentId
          ? { ...department, ...updates }
          : department
      );

      setDepartments(updatedDepartments);
      setLoading(false);

      const updatedDepartment = updatedDepartments.find(
        (d) => d.id === departmentId
      );
      if (!updatedDepartment) {
        throw new Error("Department not found after update");
      }

      return updatedDepartment;
    } catch (err) {
      setError(
        err instanceof Error ? err : new Error("Failed to update department")
      );
      setLoading(false);
      throw err;
    }
  };

  // Delete a department
  const deleteDepartment = async (departmentId: string): Promise<void> => {
    setLoading(true);
    try {
      // In a real app, this would be an API call
      // await axios.delete<ApiResponse<void>>(`/api/departments/${departmentId}`);

      // For now, simulate API response
      setDepartments((prev) =>
        prev.filter((department) => department.id !== departmentId)
      );

      // If the deleted department was selected, select another department
      if (selectedDepartmentId === departmentId) {
        const remaining = departments.filter(
          (department) => department.id !== departmentId
        );
        if (remaining.length > 0) {
          setSelectedDepartmentId(remaining[0].id);
        } else {
          setSelectedDepartmentId("");
        }
      }

      setLoading(false);
    } catch (err) {
      setError(
        err instanceof Error ? err : new Error("Failed to delete department")
      );
      setLoading(false);
      throw err;
    }
  };

  // Add a sub-department
  const addSubDepartment = async (
    parentDepartmentId: string,
    name: string
  ): Promise<Department> => {
    const subdepartment: Partial<Department> = {
      name,
      parentDepartmentId,
    };

    return createDepartment(subdepartment);
  };

  // Toggle expand/collapse for a department
  const toggleDepartmentExpand = (departmentId: string) => {
    setDepartments((prev) =>
      prev.map((department) =>
        department.id === departmentId
          ? { ...department, isExpanded: !department.isExpanded }
          : department
      )
    );
  };

  // Get root-level departments (no parent)
  const getRootDepartments = () => {
    return departments.filter((department) => !department.parentDepartmentId);
  };

  // Get sub-departments of a department
  const getSubDepartments = (parentDepartmentId: string) => {
    return departments.filter(
      (department) => department.parentDepartmentId === parentDepartmentId
    );
  };

  // Select a department
  const selectDepartment = (departmentId: string) => {
    setSelectedDepartmentId(departmentId);
  };

  // Load departments when unitId changes
  useEffect(() => {
    fetchDepartments();
  }, [unitId]);

  return {
    departments,
    selectedDepartmentId,
    selectedDepartment: departments.find(
      (department) => department.id === selectedDepartmentId
    ),
    loading,
    error,
    fetchDepartments,
    createDepartment,
    updateDepartment,
    deleteDepartment,
    addSubDepartment,
    toggleDepartmentExpand,
    getRootDepartments,
    getSubDepartments,
    selectDepartment,
  };
};
