import { useState } from "react";
import {
  getProjectReport,
  getTimeEntriesReport,
  getProjectCostingReport,
  getTimesheetReport,
  getClockinReport,
  updateTimesheetEntry,
  bulkUploadTimesheet,
  getLeaveAnalytics,
  getPMReport,
  getProjectManagementReport,
  getPerformanceReport,
  getEmployeeProductivity,
  type ReportFilters,
  type ProjectCostingFilters,
  type TimesheetReportFilters,
  type ClockinReportFilters,
  type UpdateTimesheetEntryData,
  type LeaveAnalyticsFilters,
} from "../../services/reportService";
import { handleToastError } from "../../utils";

function useReportService() {
  const [loading, setLoading] = useState(false);

  // Get Project Report
  const getProjectReportAsync = async (filters?: ReportFilters) => {
    try {
      setLoading(true);
      const response = await getProjectReport(filters);

      // Axios wraps the response, so response.data is the actual API response
      // API response structure: { success, code, message, data: { summary, charts } }
      const apiResponse = response.data;

      if (apiResponse?.success !== false) {
        // Check if data exists
        if (apiResponse?.data) {
          return {
            success: true,
            data: apiResponse.data, // This contains { summary, charts }
            message: apiResponse?.message || "Report data fetched successfully",
          };
        } else {
          // If no data, return empty structure
          return {
            success: true,
            data: {
              summary: {
                total_hours: 0,
                total_cost: 0,
                total_clients: 0,
                total_projects: 0,
                total_employees: 0,
              },
              charts: {
                hours_by_project: [],
                cost_by_project: [],
                hours_by_activity_type: [],
                hours_by_employee: [],
                daily_hours_trend: [],
              },
            },
            message: apiResponse?.message || "No data available",
          };
        }
      } else {
        const errorMessage =
          apiResponse?.message || "Failed to fetch report data";
        handleToastError(errorMessage);
        return {
          success: false,
          data: null,
          message: errorMessage,
        };
      }
    } catch (error: any) {
      setLoading(false);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    } finally {
      setLoading(false);
    }
  };

  // Get Time Entries Report
  const getTimeEntriesReportAsync = async (
    filters?: ReportFilters & { page?: number; limit?: number },
  ) => {
    try {
      setLoading(true);
      const response = await getTimeEntriesReport(filters);

      const apiResponse = response.data;

      if (apiResponse?.success !== false) {
        if (apiResponse?.data) {
          return {
            success: true,
            data: apiResponse.data,
            message:
              apiResponse?.message ||
              "Time entries report fetched successfully",
          };
        } else {
          return {
            success: true,
            data: {
              summary: {
                total_entries: 0,
                total_hours: 0,
                total_cost: 0,
              },
              entries: [],
              total_count: 0,
              current_page: 1,
              per_page: 10,
              total_pages: 0,
            },
            message: apiResponse?.message || "No data available",
          };
        }
      } else {
        const errorMessage =
          apiResponse?.message || "Failed to fetch time entries report";
        handleToastError(errorMessage);
        return {
          success: false,
          data: null,
          message: errorMessage,
        };
      }
    } catch (error: any) {
      setLoading(false);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    } finally {
      setLoading(false);
    }
  };

  // Get Project Costing Report
  const getProjectCostingReportAsync = async (
    filters?: ProjectCostingFilters,
  ) => {
    try {
      setLoading(true);
      const response = await getProjectCostingReport(filters);

      const apiResponse = response.data;

      if (apiResponse?.success !== false) {
        if (apiResponse?.data) {
          return {
            success: true,
            data: apiResponse.data,
            message:
              apiResponse?.message ||
              "Project costing report fetched successfully",
          };
        } else {
          return {
            success: true,
            data: {
              summary: {
                total_projects: 0,
                total_cost: 0,
                average_cost_per_project: 0,
              },
              projects: [],
              total_count: 0,
              current_page: 1,
              per_page: 10,
              total_pages: 0,
            },
            message: apiResponse?.message || "No data available",
          };
        }
      } else {
        const errorMessage =
          apiResponse?.message || "Failed to fetch project costing report";
        handleToastError(errorMessage);
        return {
          success: false,
          data: null,
          message: errorMessage,
        };
      }
    } catch (error: any) {
      setLoading(false);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    } finally {
      setLoading(false);
    }
  };

  // Get Timesheet Report
  const getTimesheetReportAsync = async (filters?: TimesheetReportFilters) => {
    try {
      setLoading(true);
      const response = await getTimesheetReport(filters);

      const apiResponse = response.data;

      if (apiResponse?.success !== false) {
        if (apiResponse?.data) {
          return {
            success: true,
            data: apiResponse.data,
            message:
              apiResponse?.message || "Timesheet report fetched successfully",
          };
        } else {
          return {
            success: true,
            data: {
              summary: {
                total_records: 0,
                total_hours_all_records: "00:00",
                employees_present: 0,
                total_employees: 0,
                average_hours_per_employee_per_day: "00:00",
              },
              entries: [],
              total_count: 0,
              current_page: 1,
              per_page: 10,
              total_pages: 0,
            },
            message: apiResponse?.message || "No data available",
          };
        }
      } else {
        const errorMessage =
          apiResponse?.message || "Failed to fetch timesheet report";
        handleToastError(errorMessage);
        return {
          success: false,
          data: null,
          message: errorMessage,
        };
      }
    } catch (error: any) {
      setLoading(false);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    } finally {
      setLoading(false);
    }
  };

  // Get Clock-in Report
  const getClockinReportAsync = async (filters?: ClockinReportFilters) => {
    try {
      setLoading(true);
      const response = await getClockinReport(filters);

      const apiResponse = response.data;

      if (apiResponse?.success !== false) {
        if (apiResponse?.data) {
          return {
            success: true,
            data: apiResponse.data,
            message:
              apiResponse?.message || "Clock-in report fetched successfully",
          };
        } else {
          return {
            success: true,
            data: {
              entries: [],
              total_count: 0,
              current_page: 1,
              per_page: 10,
              total_pages: 0,
            },
            message: apiResponse?.message || "No data available",
          };
        }
      } else {
        const errorMessage =
          apiResponse?.message || "Failed to fetch clock-in report";
        handleToastError(errorMessage);
        return {
          success: false,
          data: null,
          message: errorMessage,
        };
      }
    } catch (error: any) {
      setLoading(false);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    } finally {
      setLoading(false);
    }
  };

  // Update Timesheet Entry
  const updateTimesheetEntryAsync = async (data: UpdateTimesheetEntryData) => {
    // Validate that ID is present
    if (!data.id || data.id === null || data.id === undefined) {
      const errorMessage = "Timesheet entry ID is required for update";
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    }

    // Validate required fields (employee_id is not required as it's read-only)
    if (!data.clock_in || !data.description?.trim()) {
      const errorMessage = "Clock in time and description are required";
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    }

    try {
      setLoading(true);
      console.log("[Hook] Calling updateTimesheetEntry API:", {
        id: data.id,
        employee_id: data.employee_id,
        clock_in: data.clock_in,
        clock_out: data.clock_out,
        description: data.description,
      });

      const response = await updateTimesheetEntry(data);
      const apiResponse = response.data;

      console.log("[Hook] API Response:", apiResponse);

      if (apiResponse?.success !== false) {
        return {
          success: true,
          data: apiResponse.data,
          message:
            apiResponse?.message || "Timesheet entry updated successfully",
        };
      } else {
        const errorMessage =
          apiResponse?.message || "Failed to update timesheet entry";
        handleToastError(errorMessage);
        return {
          success: false,
          data: null,
          message: errorMessage,
        };
      }
    } catch (error: any) {
      setLoading(false);
      console.error("[Hook] Error in updateTimesheetEntryAsync:", error);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    } finally {
      setLoading(false);
    }
  };

  // Bulk Upload Timesheet
  const bulkUploadTimesheetAsync = async (file: File) => {
    try {
      setLoading(true);
      const response = await bulkUploadTimesheet(file);

      // Axios wraps the response, so response.data is the actual API response
      const apiResponse = response.data;

      if (apiResponse?.success !== false) {
        return {
          success: true,
          data: apiResponse.data,
          message:
            apiResponse?.message ||
            "Timesheet bulk upload completed successfully",
        };
      } else {
        const errorMessage =
          apiResponse?.message || "Failed to upload timesheet data";
        handleToastError(errorMessage);
        return {
          success: false,
          data: null,
          message: errorMessage,
        };
      }
    } catch (error: any) {
      setLoading(false);
      console.error("[Hook] Error in bulkUploadTimesheetAsync:", error);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    } finally {
      setLoading(false);
    }
  };

  // Get Leave Analytics Report
  const getLeaveAnalyticsAsync = async (filters?: LeaveAnalyticsFilters) => {
    try {
      setLoading(true);
      const response = await getLeaveAnalytics(filters);

      const apiResponse = response.data;

      if (apiResponse?.success !== false) {
        if (apiResponse?.data) {
          return {
            success: true,
            data: apiResponse.data,
            message:
              apiResponse?.message || "Leave analytics fetched successfully",
          };
        } else {
          return {
            success: true,
            data: {
              employee_wise_leaves: [],
              monthly_leave_count: [],
              year: filters?.year || new Date().getFullYear(),
              total_leave_days: 0,
            },
            message: apiResponse?.message || "No leave data available",
          };
        }
      } else {
        const errorMessage =
          apiResponse?.message || "Failed to fetch leave analytics";
        handleToastError(errorMessage);
        return {
          success: false,
          data: null,
          message: errorMessage,
        };
      }
    } catch (error: any) {
      setLoading(false);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    } finally {
      setLoading(false);
    }
  };

  // Get PM Report
  const getPMReportAsync = async (filters?: ReportFilters) => {
    try {
      setLoading(true);
      const response = await getPMReport(filters);

      const apiResponse = response.data;

      if (apiResponse?.success !== false) {
        if (apiResponse?.data) {
          return {
            success: true,
            data: apiResponse.data,
            message: apiResponse?.message || "PM report fetched successfully",
          };
        } else {
          return {
            success: true,
            data: {
              pm_report: [],
              summary: {
                total_tasks: 0,
                in_progress: 0,
                on_hold: 0,
                completed: 0,
              },
            },
            message: apiResponse?.message || "No PM data available",
          };
        }
      } else {
        const errorMessage =
          apiResponse?.message || "Failed to fetch PM report";
        handleToastError(errorMessage);
        return {
          success: false,
          data: null,
          message: errorMessage,
        };
      }
    } catch (error: any) {
      setLoading(false);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    } finally {
      setLoading(false);
    }
  };

  // Get Project Management Report - /reports/project-management
  const getProjectManagementReportAsync = async (filters?: ReportFilters) => {
    try {
      setLoading(true);
      const response = await getProjectManagementReport(filters);
      const apiResponse = response?.data;

      if (apiResponse?.success !== false) {
        const rawData: any = apiResponse?.data;
        const defaultMeta = {
          total_hours: 0,
          total_cost: 0,
          total_clients: 0,
          total_projects: 0,
          total_employees: 0,
        };

        if (rawData) {
          // Handle nested structure: { meta, data } or { meta, report } or { meta, pm_report }, etc.
          const meta = rawData.meta || defaultMeta;
          let pmArray =
            rawData.data ??
            rawData.report ??
            rawData.pm_report ??
            rawData.items ??
            rawData.list ??
            (Array.isArray(rawData) ? rawData : []);
          // If data is object with nested items (e.g. { items: [], total: N })
          if (
            !Array.isArray(pmArray) &&
            pmArray &&
            typeof pmArray === "object" &&
            "items" in pmArray
          ) {
            pmArray = (pmArray as { items: unknown[] }).items ?? [];
          }

          return {
            success: true,
            data: {
              meta,
              data: Array.isArray(pmArray) ? pmArray : [],
            },
            message:
              apiResponse?.message ||
              "Project management report fetched successfully",
          };
        }

        return {
          success: true,
          data: { meta: defaultMeta, data: [] },
          message: apiResponse?.message || "No data available",
        };
      }
      const errorMessage =
        apiResponse?.message || "Failed to fetch project management report";
      handleToastError(errorMessage);
      return { success: false, data: null, message: errorMessage };
    } catch (error: any) {
      setLoading(false);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return { success: false, data: null, message: errorMessage };
    } finally {
      setLoading(false);
    }
  };

  // Get Performance Report
  const getPerformanceReportAsync = async (filters?: ReportFilters) => {
    try {
      setLoading(true);
      const response = await getPerformanceReport(filters);

      const apiResponse = response.data;

      if (apiResponse?.success !== false) {
        if (apiResponse?.data) {
          return {
            success: true,
            data: apiResponse.data,
            message:
              apiResponse?.message || "Performance report fetched successfully",
          };
        } else {
          return {
            success: true,
            data: {
              summary: {
                total_hours: 0,
                total_cost: 0,
                total_clients: 0,
                total_projects: 0,
                total_employees: 0,
              },
              project_completion: [],
              hours_by_project: [],
              hours_by_activity_type: [],
              daily_hours_trend: [],
              productive_vs_non_productive: [],
            },
            message: apiResponse?.message || "No performance data available",
          };
        }
      } else {
        const errorMessage =
          apiResponse?.message || "Failed to fetch performance report";
        handleToastError(errorMessage);
        return {
          success: false,
          data: null,
          message: errorMessage,
        };
      }
    } catch (error: any) {
      setLoading(false);
      const errorMessage =
        error?.response?.data?.message || error?.message || error.toString();
      handleToastError(errorMessage);
      return {
        success: false,
        data: null,
        message: errorMessage,
      };
    } finally {
      setLoading(false);
    }
  };

  const getEmployeeProductivityAsync = async (
    filters?: import("../../services/reportService").EmployeeProductivityFilters,
  ) => {
    try {
      setLoading(true);
      const response = await getEmployeeProductivity(filters);
      const apiResponse = response.data;

      if (apiResponse?.success !== false) {
        const rawData = apiResponse?.data;
        const dataArray = Array.isArray(rawData)
          ? rawData
          : rawData
            ? [rawData]
            : [];
        return {
          success: true,
          data: dataArray,
          message:
            apiResponse?.message ||
            "Employee productivity fetched successfully",
        };
      }
      return {
        success: false,
        data: [],
        message:
          apiResponse?.message || "Failed to fetch employee productivity",
      };
    } catch (error: any) {
      setLoading(false);
      const errMsg =
        error?.response?.data?.message || error?.message || String(error);
      handleToastError(errMsg);
      return { success: false, data: [], message: errMsg };
    } finally {
      setLoading(false);
    }
  };

  return {
    loading,
    getProjectReport: getProjectReportAsync,
    getTimeEntriesReport: getTimeEntriesReportAsync,
    getProjectCostingReport: getProjectCostingReportAsync,
    getTimesheetReport: getTimesheetReportAsync,
    getClockinReport: getClockinReportAsync,
    updateTimesheetEntry: updateTimesheetEntryAsync,
    bulkUploadTimesheet: bulkUploadTimesheetAsync,
    getLeaveAnalytics: getLeaveAnalyticsAsync,
    getPMReport: getPMReportAsync,
    getProjectManagementReport: getProjectManagementReportAsync,
    getPerformanceReport: getPerformanceReportAsync,
    getEmployeeProductivity: getEmployeeProductivityAsync,
  };
}

export default useReportService;
