import axiosInstance from "./axiosInstance";
import { withHeaders } from "@/record-management/services/api/withHeaders";
import * as XLSX from "xlsx";

export interface ExportUserDataResponse {
  success: boolean;
  message: string;
  data?: unknown;
}

export const exportService = {
  /**
   * Get units list for a specific organization, including child units
     * @param organizationId - The organization ID to get units for
      * @returns Promise with units list (flattened, including all children)
   */
  getUnitsList: async (organizationId: string) => {
    try {
      // Recursive function to flatten unit hierarchy
      const flattenUnits = async (units: any[]): Promise<any[]> => {
        const result: any[] = [];
        
        for (const unit of units) {
          result.push(unit);
          
          // Try to fetch child units for this unit
          try {
            const childResponse = await axiosInstance.get(
              `/units/child-units/${unit.id}`,
              {
                headers: withHeaders(),
                params: {
                  take: 1000,
                  skip: 0,
                },
              },
            );
            
            if (childResponse.data?.items && childResponse.data.items.length > 0) {
              const flattenedChildren = await flattenUnits(childResponse.data.items);
              result.push(...flattenedChildren);
            }
          } catch (error) {
            // If child units fail to load, continue with next unit
            console.warn(`Failed to fetch child units for ${unit.id}:`, error);
          }
        }
        
        return result;
      };

      // First, get the top-level units for the organization
      const response = await axiosInstance.get(
        `/units/list/${organizationId}`,
        {
          headers: withHeaders(),
          params: {
            take: 1000,
            skip: 0,
          },
        },
      );

      // Then flatten the hierarchy to include all child units
      const allUnits = await flattenUnits(response.data?.items || []);

      return {
        success: true,
        data: {
          ...response.data,
          items: allUnits,
        },
      };
    } catch (error: unknown) {
      console.error("Failed to fetch units:", error);
      return {
        success: false,
        message:
          (error as { response?: { data?: { message?: string } } })?.response
            ?.data?.message || "Failed to fetch units",
        data: null,
      };
    }
  },

  /**
   * Export user data for a specific unit
   * @param unitId - The unit ID to export data for
   * @param format - Export format ('xlsx' or 'csv')
   * @returns Promise with export response
   */
  exportUserData: async (
    unitId: string,
    format: "xlsx" | "csv" = "xlsx",
  ): Promise<ExportUserDataResponse> => {
    try {
      const response = await axiosInstance.get(
        `/employees/export-user-data/${unitId}`,
        {
          headers: withHeaders(),
          responseType: "json", // Changed from blob to json
        },
      );

      // Convert JSON data to XLSX
      const jsonData = response.data;

      // Create a new workbook
      const workbook = XLSX.utils.book_new();

      // Handle different data structures
      if (Array.isArray(jsonData)) {
        // If it's an array, convert it to a worksheet
        const worksheet = XLSX.utils.json_to_sheet(jsonData);
        XLSX.utils.book_append_sheet(workbook, worksheet, "Data");
      } else if (jsonData && typeof jsonData === "object") {
        // If it's an object, check for positions and users arrays
        if (jsonData.positions && Array.isArray(jsonData.positions)) {
          const positionsWorksheet = XLSX.utils.json_to_sheet(
            jsonData.positions,
          );
          XLSX.utils.book_append_sheet(
            workbook,
            positionsWorksheet,
            "Positions",
          );
        }

        if (jsonData.users && Array.isArray(jsonData.users)) {
          const usersWorksheet = XLSX.utils.json_to_sheet(jsonData.users);
          XLSX.utils.book_append_sheet(workbook, usersWorksheet, "Users");
        }

        // If no positions or users found, try to find any array property
        if (!jsonData.positions && !jsonData.users) {
          const dataArray = Object.values(jsonData).find((value) =>
            Array.isArray(value),
          );
          if (dataArray) {
            const worksheet = XLSX.utils.json_to_sheet(dataArray);
            XLSX.utils.book_append_sheet(workbook, worksheet, "Data");
          } else {
            // If no array found, convert the object itself
            const worksheet = XLSX.utils.json_to_sheet([jsonData]);
            XLSX.utils.book_append_sheet(workbook, worksheet, "Data");
          }
        }
      } else {
        // If it's not an array or object, create a simple worksheet
        const worksheet = XLSX.utils.json_to_sheet([{ data: jsonData }]);
        XLSX.utils.book_append_sheet(workbook, worksheet, "Data");
      }

      // Generate file as buffer based on format
      let fileBuffer: ArrayBuffer;
      let mimeType: string;
      let fileExtension: string;

      if (format === "csv") {
        // For CSV, we need to combine all data into a single sheet
        let csvString = "";

        if (
          jsonData &&
          typeof jsonData === "object" &&
          (jsonData.positions || jsonData.users)
        ) {
          // Combine positions and users data for CSV
          const allData: Array<Record<string, unknown> & { dataType: string }> =
            [];

          if (jsonData.positions && Array.isArray(jsonData.positions)) {
            jsonData.positions.forEach((item: Record<string, unknown>) => {
              allData.push({ ...item, dataType: "Position" });
            });
          }

          if (jsonData.users && Array.isArray(jsonData.users)) {
            jsonData.users.forEach((item: Record<string, unknown>) => {
              allData.push({ ...item, dataType: "User" });
            });
          }

          if (allData.length > 0) {
            const combinedWorksheet = XLSX.utils.json_to_sheet(allData);
            csvString = XLSX.utils.sheet_to_csv(combinedWorksheet);
          }
        } else {
          // Fallback to first worksheet
          const firstSheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[firstSheetName];
          csvString = XLSX.utils.sheet_to_csv(worksheet);
        }

        fileBuffer = new TextEncoder().encode(csvString);
        mimeType = "text/csv";
        fileExtension = "csv";
      } else {
        // For XLSX
        fileBuffer = XLSX.write(workbook, {
          bookType: "xlsx",
          type: "array",
        });
        mimeType =
          "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        fileExtension = "xlsx";
      }

      // Create a blob from the file buffer
      const blob = new Blob([fileBuffer], {
        type: mimeType,
      });

      // Create a download link
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;

      // Set filename with timestamp
      const timestamp = new Date().toISOString().split("T")[0];
      const filename = `user-data-export-${timestamp}.${fileExtension}`;

      link.download = filename;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);

      return {
        success: true,
        message: "Export completed successfully",
        data: jsonData,
      };
    } catch (error: unknown) {
      console.error("Export failed:", error);
      return {
        success: false,
        message:
          (error as { response?: { data?: { message?: string } } })?.response
            ?.data?.message || "Export failed. Please try again.",
        data: null,
      };
    }
  },
};
