import { useState, useEffect } from "react";
import axios from "axios";

export type InviteStatus = "Pending" | "Accepted" | "Not Invited";
export type EmployeeRole =
  | "TeamLeader"
  | "TeamMember"
  | "Director"
  | "Manager"
  | "Regular";

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

export interface Employee {
  id: string;
  name: string;
  email?: string;
  role?: EmployeeRole;
  inviteStatus?: InviteStatus;
  title?: string;
  phone?: string;
  dateAdded?: string;
}

export const useEmployees = (positionId: string, departmentId?: string) => {
  const [employees, setEmployees] = useState<Employee[]>([]);
  const [selectedEmployeeId, setSelectedEmployeeId] = useState<string>("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<Error | null>(null);

  // Fetch employees for a position or department
  const fetchEmployees = async () => {
    if (!positionId && !departmentId) {
      setEmployees([]);
      setSelectedEmployeeId("");
      return;
    }

    setLoading(true);
    try {
      // In a real app, this would be an API call
      // if (positionId) {
      //   const response = await axios.get<ApiResponse<Employee[]>>(`/api/positions/${positionId}/employees`);
      //   setEmployees(response.data.data);
      // } else if (departmentId) {
      //   const response = await axios.get<ApiResponse<Employee[]>>(`/api/departments/${departmentId}/employees`);
      //   setEmployees(response.data.data);
      // }

      // For now, simulate API response with mock data
      setTimeout(() => {
        const mockEmployees: Employee[] = [
          {
            id: "emp1",
            name: "Abebe Kebede",
            email: "abebe@example.com",
            role: "Director",
            title: "Department Director",
            phone: "+251911123456",
            dateAdded: "2023-05-15",
            inviteStatus: "Accepted",
          },
          {
            id: "emp2",
            name: "Kebede Abebe",
            email: "kebede@example.com",
            role: "TeamLeader",
            title: "Team Lead - Development",
            phone: "+251922123456",
            dateAdded: "2023-06-20",
            inviteStatus: "Pending",
          },
          {
            id: "emp3",
            name: "Chala Demeke",
            email: "chala@example.com",
            role: "TeamMember",
            title: "Senior Developer",
            phone: "+251933123456",
            dateAdded: "2023-07-10",
            inviteStatus: "Not Invited",
          },
          {
            id: "emp4",
            name: "Tigist Alemu",
            email: "tigist@example.com",
            role: "Manager",
            title: "Project Manager",
            phone: "+251944123456",
            dateAdded: "2023-08-05",
            inviteStatus: "Accepted",
          },
        ];

        setEmployees(mockEmployees);
        if (mockEmployees.length > 0) {
          setSelectedEmployeeId(mockEmployees[0].id);
        } else {
          setSelectedEmployeeId("");
        }
        setLoading(false);
      }, 500);
    } catch (err) {
      setError(
        err instanceof Error ? err : new Error("Failed to fetch employees")
      );
      setLoading(false);
    }
  };

  // Create a new employee
  const createEmployee = async (
    employeeData: Partial<Employee>
  ): Promise<Employee> => {
    if (!positionId && !departmentId) {
      throw new Error("No position or department selected");
    }

    setLoading(true);
    try {
      // In a real app, this would be an API call
      // let response;
      // if (positionId) {
      //   response = await axios.post<ApiResponse<Employee>>(
      //     `/api/positions/${positionId}/employees`,
      //     employeeData
      //   );
      // } else if (departmentId) {
      //   response = await axios.post<ApiResponse<Employee>>(
      //     `/api/departments/${departmentId}/employees`,
      //     employeeData
      //   );
      // } else {
      //   throw new Error('No position or department ID provided');
      // }
      // const newEmployee = response.data.data;

      // For now, simulate API response
      const newEmployee: Employee = {
        id: `emp-${Date.now()}`,
        name: employeeData.name || "New Employee",
        email: employeeData.email,
        role: employeeData.role || "Regular",
        title: employeeData.title,
        phone: employeeData.phone,
        dateAdded: new Date().toISOString().split("T")[0],
        inviteStatus: employeeData.inviteStatus || "Not Invited",
      };

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

  // Update an existing employee
  const updateEmployee = async (
    employeeId: string,
    updates: Partial<Employee>
  ): Promise<Employee> => {
    setLoading(true);
    try {
      // In a real app, this would be an API call
      // const response = await axios.put<ApiResponse<Employee>>(
      //   `/api/employees/${employeeId}`,
      //   updates
      // );
      // const updatedEmployee = response.data.data;

      // For now, simulate API response
      const updatedEmployees = employees.map((employee) =>
        employee.id === employeeId ? { ...employee, ...updates } : employee
      );

      setEmployees(updatedEmployees);
      setLoading(false);

      const updatedEmployee = updatedEmployees.find((e) => e.id === employeeId);
      if (!updatedEmployee) {
        throw new Error("Employee not found after update");
      }

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

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

      // For now, simulate API response
      setEmployees((prev) =>
        prev.filter((employee) => employee.id !== employeeId)
      );

      // If the deleted employee was selected, select another employee
      if (selectedEmployeeId === employeeId) {
        const remaining = employees.filter(
          (employee) => employee.id !== employeeId
        );
        if (remaining.length > 0) {
          setSelectedEmployeeId(remaining[0].id);
        } else {
          setSelectedEmployeeId("");
        }
      }

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

  // Send invitation to an employee
  const inviteEmployee = async (employeeId: string): Promise<string> => {
    setLoading(true);
    try {
      // In a real app, this would be an API call
      // const response = await axios.post<ApiResponse<{ inviteLink: string }>>(
      //   `/api/employees/${employeeId}/invite`
      // );
      // return response.data.data.inviteLink;

      // For now, simulate API response
      return new Promise((resolve) => {
        setTimeout(() => {
          const inviteLink = `https://example.com/invite/${employeeId}-${Date.now()}`;

          // Update employee status in state
          setEmployees((prev) =>
            prev.map((employee) =>
              employee.id === employeeId
                ? { ...employee, inviteStatus: "Pending" as InviteStatus }
                : employee
            )
          );

          setLoading(false);
          resolve(inviteLink);
        }, 1000);
      });
    } catch (err) {
      setError(
        err instanceof Error ? err : new Error("Failed to send invitation")
      );
      setLoading(false);
      throw err;
    }
  };

  // Get invite status for an employee
  const getInviteStatus = async (employeeId: string): Promise<InviteStatus> => {
    setLoading(true);
    try {
      // In a real app, this would be an API call
      // const response = await axios.get<ApiResponse<{ status: InviteStatus }>>(
      //   `/api/employees/${employeeId}/invite-status`
      // );
      // return response.data.data.status;

      // For now, simulate API response
      return new Promise((resolve) => {
        setTimeout(() => {
          const employee = employees.find((e) => e.id === employeeId);
          setLoading(false);
          resolve(employee?.inviteStatus || "Not Invited");
        }, 500);
      });
    } catch (err) {
      setError(
        err instanceof Error
          ? err
          : new Error("Failed to get invitation status")
      );
      setLoading(false);
      throw err;
    }
  };

  // Select an employee
  const selectEmployee = (employeeId: string) => {
    setSelectedEmployeeId(employeeId);
  };

  // Filter employees by role
  const getEmployeesByRole = (role: EmployeeRole) => {
    return employees.filter((employee) => employee.role === role);
  };

  // Filter employees by invite status
  const getEmployeesByInviteStatus = (status: InviteStatus) => {
    return employees.filter((employee) => employee.inviteStatus === status);
  };

  // Load employees when positionId or departmentId changes
  useEffect(() => {
    fetchEmployees();
  }, [positionId, departmentId]);

  return {
    employees,
    selectedEmployeeId,
    selectedEmployee: employees.find(
      (employee) => employee.id === selectedEmployeeId
    ),
    loading,
    error,
    fetchEmployees,
    createEmployee,
    updateEmployee,
    deleteEmployee,
    inviteEmployee,
    getInviteStatus,
    selectEmployee,
    getEmployeesByRole,
    getEmployeesByInviteStatus,
  };
};
