import { generateQueryString } from "@/utils/queryStringUtil";
import { apiSlice } from ".";
import URLS from "./constants";
import {
  BulkLeadUploadResultData,
  LeadAnalyticsResponse,
} from "@/types/lead";

export interface Lead {
  _id: string;
  id?: string;
  createdAt: string;
  updatedAt: string;

  fullName: string;
  email: string;
  phone: string;
  status: string;
  sourceId: string;
  companyId: string;
  assignedTo?: { id?: string };
  contact?: { companyName?: string };

  // Example populated fields
  source?: {
    _id: string;
    name: string;
  };
  company?: {
    _id: string;
    name: string;
  };
  success?: string;
  message?: string;
  data?: Lead;
}

interface GetLeadListResponse {
  data: {
    results: Lead[];
    page: number;
    limit: number;
    totalPages: number;
    totalResults: number;
  };
  code: number;
  message: string;
  success: boolean;
  error?: object;
}

interface GetLeadByIdResponse {
  data: Lead;
  code: number;
  message: string;
  success: boolean;
  error?: object;
}

export interface CreateLeadBody {
  fullName: string;
  email: string;
  phone: string;
  status: string;
  sourceId: string;
  companyId: string;
  assignedTo?: string;
}

export interface SuggestedProperty {
  id: string;
  title: string;
  subcategory: {
    _id: string;
    name: string;
  };
  status: string;
  configuration: {
    _id: string;
    name: string;
  };
  locality: {
    _id: string;
    name: string;
  };
  city: {
    _id: string;
    name: string;
  };
  state?: {
    _id: string;
    name: string;
  };
  ownerName: string;
  ownerContact: string;
  price: number;
  monthlyRent?: number | null;
  availability: string;
  createdBy: { firstName: string };
}

interface GetSuggestedPropertiesResponse {
  code: number;
  message: string;
  data: SuggestedProperty[];
  success: boolean;
}

type UpdateLeadBody = Partial<CreateLeadBody>;

export interface BulkLeadPayload {
  assignedTo?: string;
  budget?: string;
  buyingPreference?: string;
  firstName: string;
  interestType: string;
  phone: string;
  project?: string;
  source: string;
  unit?: string;
}

export interface BulkUploadApiResponse {
  code: number;
  message: string;
  data: BulkLeadUploadResultData;
  success: boolean;
  error?: object;
}

export interface TransferLeadBody {
  sourceMember: string;
  destMember: string;
  transferType: "temporary" | "permanent";
  leadTypes: "all" | "selected";
  transferStartDate?: string;
  transferEndDate?: string;
}

export interface TransferLeadResponse {
  code: number;
  message: string;
  success: boolean;
  data: {
    count: number;
    transferType: "temporary" | "permanent";
    destMember: string;
  };
}

export interface SuggestedProject {
  id: string;
  projectName: string;
  status: string;
  locality: {
    _id: string;
    name: string;
  };
  city: {
    _id: string;
    name: string;
  };
  state: {
    _id: string;
    name: string;
  };
  pricePerSqYard: number;
  createdBy: {
    _id: string;
    firstName: string;
    lastName: string;
  };
  companyId: string;
  mediaUrls: string[];
}

interface GetSuggestedProjectsResponse {
  code: number;
  message: string;
  data: SuggestedProject[];
  success: boolean;
}

export const leadApi = apiSlice.injectEndpoints({
  endpoints: (builder) => ({
    getLeads: builder.query<
      GetLeadListResponse,
      {
        page?: number;
        limit?: number;
        search?: string;
        sortBy?: string;
        populate?: string;
        status?: string;
        alias?: string;
        includeTimeStamps?: boolean;
        leadStage?: string;
        companyName?: string;
        company?: string;
        interestType?: string;
        source?: string;
        preferredCity?: any;
        preferredLocalities?: any;
        budget?: any;
        category?: any;
        propertyType?: any;
      }
    >({
      query: (params) => ({
        url: `${URLS.LEAD}?${generateQueryString(
          params as Record<string, unknown>
        )}`,
        method: "GET",
      }),
      providesTags: ["Lead"],
    }),

    getLeadById: builder.query<GetLeadByIdResponse, string>({
      query: (id) => ({
        url: `${URLS.LEAD}/${id}`,
        method: "GET",
      }),
      providesTags: ["Lead"],
    }),

    createLead: builder.mutation<Lead, CreateLeadBody>({
      query: (body) => ({
        url: `${URLS.LEAD}`,
        method: "POST",
        body,
      }),
      invalidatesTags: ["Lead"],
    }),

    updateLead: builder.mutation<
      Lead,
      { id: string; body: UpdateLeadBody; checkCustomFieldValidation?: boolean }
    >({
      query: ({ id, body, checkCustomFieldValidation }) => {
        const params =
          checkCustomFieldValidation !== undefined
            ? { checkCustomFieldValidation }
            : undefined;

        return {
          url: `${URLS.LEAD}/${id}`,
          method: "PATCH",
          params,
          body,
        };
      },
      invalidatesTags: (result, error, { id }) => [
        { type: "Lead", id },
        "Lead",
      ],
    }),

    deleteLead: builder.mutation<{ success: boolean }, string>({
      query: (id) => ({
        url: `${URLS.LEAD}/${id}`,
        method: "DELETE",
      }),
      invalidatesTags: (result, error, id) => [{ type: "Lead", id }, "Lead"],
    }),

    checkRefLead: builder.query({
      query: (id) => ({
        url: `${URLS.LEAD}/${id}/referenceLead`,
        method: "GET",
      }),
    }),

    getLeadAnalytics: builder.query<LeadAnalyticsResponse, void>({
      query: () => ({
        url: `${URLS.LEAD}/analytics`,
        method: "GET",
      }),
    }),

    getSuggestedProperties: builder.query<
      GetSuggestedPropertiesResponse,
      { id?: string; model?: string }
    >({
      query: ({ id, model }) => ({
        url: `${URLS.LEAD}/suggestedProperties/${id}?model=${model}`,
        method: "GET",
      }),
      providesTags: (result, error, { model }) =>
        model === "contact" ? ["Contact"] : ["Lead"],
    }),

    updateLeadShortList: builder.mutation<
      {
        code: number;
        message: string;
        data: SuggestedProperty;
        success: boolean;
      },
      {
        entityId?: string;
        type: "add" | "remove" | "delete";
        propertyId?: string; // optional
        projectId?: string; // optional
        model?: string;
      }
    >({
      query: ({ entityId, type, propertyId, projectId, model }) => {
        const params = new URLSearchParams({ type });

        if (propertyId) {
          params.append("propertyId", propertyId);
        } else if (projectId) {
          params.append("projectId", projectId);
        }

        if (model) {
          params.append("model", model);
        }

        return {
          url: `${URLS.LEAD}/shortList/${entityId}?${params.toString()}`,
          method: "PATCH",
        };
      },
      invalidatesTags: (result, error, { model }) =>
        model === "contact"
          ? ["Contact", "Activity"]
          : ["Lead", "Activity"],
    }),

    bulkUploadLeads: builder.mutation<
      BulkUploadApiResponse,
      BulkLeadPayload[]
    >({
      query: (body) => ({
        url: `${URLS.LEAD}/bulkUpload`,
        method: "POST",
        body,
      }),
      invalidatesTags: ["Lead"],
    }),
    transferLead: builder.mutation<TransferLeadResponse, TransferLeadBody>({
      query: (body) => ({
        url: `${URLS.LEAD}/transferLead`,
        method: "POST",
        body,
      }),
      invalidatesTags: ["Lead"],
    }),

    getSuggestedProjects: builder.query<
      GetSuggestedProjectsResponse,
      { id?: string; model?: string }
    >({
      query: ({ id, model }) => ({
        url: `${URLS.LEAD}/suggestedProjects/${id}?model=${model}`,
        method: "GET",
      }),
      providesTags: (result, error, { model }) =>
        model === "contact" ? ["Contact"] : ["Lead"],
    }),
  }),
  overrideExisting: false,
});

export const {
  useGetLeadsQuery,
  useGetLeadByIdQuery,
  useCreateLeadMutation,
  useUpdateLeadMutation,
  useDeleteLeadMutation,
  useGetLeadAnalyticsQuery,
  useGetSuggestedPropertiesQuery,
  useUpdateLeadShortListMutation,
  useBulkUploadLeadsMutation,
  useTransferLeadMutation,
  useGetSuggestedProjectsQuery,
  useCheckRefLeadQuery,
} = leadApi;
