import { apiSlice } from "./index";
import URLS from "./constants";
import { generateQueryString } from "@/utils/queryStringUtil";
import {
  CreateProjectBody,
  CreateProjectFromSearchErrorResponse,
  CreateProjectFromSearchParams,
  CreateProjectFromSearchResponse,
  CreateUnitBody,
  GetProjectByIdResponse,
  GetProjectListResponse,
  GetProjectsAnalyticsResponse,
  GetProjectsParams,
  GetUnitByIdResponse,
  GetUnitListResponse,
  GetUnitsAnalyticsResponse,
  GetUnitsParams,
  Project,
  ProjectSearchResponse,
  SearchProjectsParams,
  Unit,
  UpdateProjectAmenitiesBody,
  UpdateProjectBody,
  UpdateUnitBody,
  UploadUnitsExcelRequest,
  UploadUnitsExcelResponse,
} from "@/types/project";

interface ProjectVisibilityResponse {
  data: {
    visibleToUsers: Array<string | { id?: string; _id?: string }>;
    visibleToTeams: Array<string | { id?: string; _id?: string }>;
  };
  code: number;
  message: string;
  success: boolean;
  error?: object;
}

interface UpdateProjectVisibilityPayload {
  projectId: string;
  visibleToUsers: string[];
  visibleToTeams: string[];
}

interface BulkUpdateProjectVisibilityPayload {
  projectIds: string[];
  isPublicVisibility: boolean;
}

export const projectApi = apiSlice.injectEndpoints({
  endpoints: (builder) => ({
    getProjects: builder.query<GetProjectListResponse, GetProjectsParams>({
      query: (params) => ({
        url: `${URLS.PROJECT}?${generateQueryString(
          params as Record<string, unknown>,
        )}`,
        method: "GET",
      }),
      providesTags: ["Project"],
    }),

    getProjectById: builder.query<GetProjectByIdResponse, string>({
      query: (id) => ({
        // Populate linked location/type data so forms can auto-prefill
        url: `${URLS.PROJECT}/${id}?populate=propertyType;state;city;locality;subCategory;amenities;companyId`,
        method: "GET",
      }),
      providesTags: ["Project"],
    }),

    createProject: builder.mutation<Project, CreateProjectBody>({
      query: (body) => ({
        url: `${URLS.PROJECT}`,
        method: "POST",
        body,
      }),
      invalidatesTags: ["Project"],
    }),

    updateProject: builder.mutation<
      Project,
      { id: string; body: UpdateProjectBody }
    >({
      query: ({ id, body }) => ({
        url: `${URLS.PROJECT}/${id}`,
        method: "PATCH",
        body,
      }),
      invalidatesTags: ["Project"],
    }),

    deleteProject: builder.mutation<{ success: boolean }, string>({
      query: (id) => ({
        url: `${URLS.PROJECT}/${id}`,
        method: "DELETE",
      }),
      invalidatesTags: ["Project"],
    }),

    searchProjects: builder.query<ProjectSearchResponse, SearchProjectsParams>({
      query: (params) => ({
        url: `${URLS.PROJECT}/search?${generateQueryString(params)}`,
        method: "GET",
      }),
      keepUnusedDataFor: 0,
    }),

    createProjectFromSearch: builder.mutation<
      CreateProjectFromSearchResponse | CreateProjectFromSearchErrorResponse,
      CreateProjectFromSearchParams
    >({
      query: (params) => ({
        url: `${URLS.PROJECT}/create-from-search`,
        method: "POST",
        body: params,
      }),
    }),

    updateProjectAmenities: builder.mutation<
      Project,
      { id: string; body: UpdateProjectAmenitiesBody }
    >({
      query: ({ id, body }) => ({
        url: `${URLS.PROJECT}/${id}/amenities`,
        method: "PATCH",
        body,
      }),
      invalidatesTags: ["Project"],
    }),

    // Unit related endpoints
    getUnitsByProjectId: builder.query<GetUnitListResponse, GetUnitsParams>({
      query: ({ projectId, ...params }) => ({
        // Default sorting for all unit dropdowns/tables unless explicitly overridden
        url: `${URLS.PROJECT}/${projectId}/units?${generateQueryString(
          ({
            sortBy: "block:asc,unitNumber:asc",
            ...params,
          } as Record<string, unknown>),
        )}`,
        method: "GET",
      }),
      providesTags: ["ProjectUnits"],
    }),

    getUnitById: builder.query<
      GetUnitByIdResponse,
      { projectId: string; unitId: string }
    >({
      query: ({ projectId, unitId }) => ({
        url: `${URLS.PROJECT}/${projectId}/units/${unitId}`,
        method: "GET",
      }),
      providesTags: ["ProjectUnits"],
    }),

    createUnit: builder.mutation<
      Unit,
      { projectId: string; body: CreateUnitBody }
    >({
      query: ({ projectId, body }) => ({
        url: `${URLS.PROJECT}/${projectId}/units`,
        method: "POST",
        body,
      }),
      invalidatesTags: ["ProjectUnits"],
    }),

    updateUnit: builder.mutation<
      Unit,
      { projectId: string; unitId: string; body: UpdateUnitBody }
    >({
      query: ({ projectId, unitId, body }) => ({
        url: `${URLS.PROJECT}/${projectId}/units/${unitId}`,
        method: "PATCH",
        body,
      }),
      invalidatesTags: ["ProjectUnits"],
    }),

    deleteUnit: builder.mutation<
      { success: boolean },
      { projectId: string; unitId: string }
    >({
      query: ({ projectId, unitId }) => ({
        url: `${URLS.PROJECT}/${projectId}/units/${unitId}`,
        method: "DELETE",
      }),
      invalidatesTags: ["ProjectUnits"],
    }),

    getUnitsAnalytics: builder.query<
      GetUnitsAnalyticsResponse,
      { projectId: string }
    >({
      query: ({ projectId }) => ({
        url: `${URLS.PROJECT}/${projectId}/units/analytics`,
        method: "GET",
      }),
      providesTags: ["ProjectUnits"],
    }),

    getProjectsAnalytics: builder.query<GetProjectsAnalyticsResponse, void>({
      query: () => ({
        url: `${URLS.PROJECT}/analytics`,
        method: "GET",
      }),
    }),

    // Project visibility
    getProjectVisibility: builder.query<ProjectVisibilityResponse, string>({
      query: (projectId) => ({
        url: `${URLS.PROJECT}/${projectId}/visibility`,
        method: "GET",
      }),
      providesTags: ["Project"],
    }),

    updateProjectVisibility: builder.mutation<
      ProjectVisibilityResponse,
      UpdateProjectVisibilityPayload
    >({
      query: ({ projectId, visibleToUsers, visibleToTeams }) => ({
        url: `${URLS.PROJECT}/${projectId}/visibility`,
        method: "PATCH",
        body: { visibleToUsers, visibleToTeams },
      }),
      invalidatesTags: ["Project"],
    }),

    bulkUpdateProjectVisibility: builder.mutation<
      { success: boolean },
      BulkUpdateProjectVisibilityPayload
    >({
      query: (body) => ({
        url: `${URLS.PROJECT}/visibility/bulk-update`,
        method: "PATCH",
        body,
      }),
      invalidatesTags: ["Project"],
    }),

    uploadUnitsExcel: builder.mutation<
      UploadUnitsExcelResponse,
      UploadUnitsExcelRequest
    >({
      query: ({ projectId, propertyType, file }) => {
        const formData = new FormData();
        formData.append("file", file);
        formData.append("propertyType", propertyType);

        return {
          url: `${URLS.PROJECT}/${projectId}/units/upload-excel`,
          method: "POST",
          body: formData,
          formData: true,
        };
      },
      transformResponse: (response: UploadUnitsExcelResponse) => response,
      invalidatesTags: ["ProjectUnits"],
    }),

    // Note: Excel template download is now handled by useFileDownload hook
    // to avoid Redux serialization issues with Blob objects
  }),
});

export const {
  useGetProjectsQuery,
  useGetProjectByIdQuery,
  useCreateProjectMutation,
  useUpdateProjectMutation,
  useLazyGetProjectByIdQuery,
  useDeleteProjectMutation,
  useSearchProjectsQuery,
  useCreateProjectFromSearchMutation,
  useUpdateProjectAmenitiesMutation,
  // Unit related hooks
  useGetUnitsByProjectIdQuery,
  useGetUnitByIdQuery,
  useCreateUnitMutation,
  useUpdateUnitMutation,
  useDeleteUnitMutation,
  useGetUnitsAnalyticsQuery,
  useUploadUnitsExcelMutation,
  useGetProjectsAnalyticsQuery,
  useGetProjectVisibilityQuery,
  useUpdateProjectVisibilityMutation,
  useBulkUpdateProjectVisibilityMutation,
} = projectApi;
