import {
  RecordDto,
  RecordPayload,
} from "@/record-management/dto/userRecords/userRecordsDto";
import recordAxiosInstance from "@/shared/services/recordAxiosInstance";

import { withHeaders } from "./withHeaders";
import { RecordVerificationDto } from "@/record-management/dto/userRecords/recordVerificationDto";

export interface PaginationParams {
  skip?: number;
  take?: number;
  status?: string;
  subject?: string;
  to?: string;
  receiverPosition?: string;
  referenceNumber?: string;
  fromCreatedAt?: string;
  toCreatedAt?: string;
  orderBy?: string;
}

export interface PaginatedResponse {
  items: RecordDto[];
  count: number;
}

export interface RecordContentHistoryEmployeeName {
  am?: string;
  en?: string;
}

export interface RecordContentOutgoingHistory {
  action?: string;
  createdAt?: string;
  comment?: string;
  id: string;
  version?: number;
  employeePosition?: {
    id: string;
    employee?: {
      id: string;
      name?: RecordContentHistoryEmployeeName;
    };
  };
}

export interface RecordContentByRecordIdResponse {
  id: string;
  isCurrent?: boolean;
  ccPositions?: {
    position?: {
      id?: string;
    };
  }[];
  outgoingHistories?: RecordContentOutgoingHistory[];
}

/**
 * GET /records/mine
 * --------------------------------------------------
 * Fetch records created by the current user.
 */
export const fetchMyRecords = async (
  params?: PaginationParams,
): Promise<PaginatedResponse> => {
  const { data } = await recordAxiosInstance.get<PaginatedResponse>(
    "/records/mine",
    {
      params,
      headers: withHeaders(),
    },
  );

  return data;
};
export const fetchMyRecordsParent = async (
  params?: PaginationParams,
): Promise<PaginatedResponse> => {
  const { data } = await recordAxiosInstance.get<PaginatedResponse>(
    "records/my-parent",
    {
      params,
      headers: withHeaders(),
    },
  );

  return data;
};

/**
 * POST /records
 * --------------------------------------------------
 * Create a new record.
 */
export const createRecord = async <T = any>(payload: T): Promise<RecordDto> => {
  const { data } = await recordAxiosInstance.post<T>("/records", payload, {
    headers: withHeaders(),
  });

  return data as RecordDto;
};

export const makeSecureRecord = async <T = any>(
  id: string,
): Promise<RecordDto> => {
  const { data } = await recordAxiosInstance.patch<T>(
    `/records/make-secured/${id}`,
    {
      isSecured: true,
    },
    {
      headers: withHeaders(),
    },
  );

  return data as RecordDto;
};

export const unMakeSecureRecord = async <T = any>(
  id: string,
): Promise<RecordDto> => {
  const { data } = await recordAxiosInstance.patch<T>(
    `/records/make-secured/${id}`,
    {
      isSecured: false,
    },
    {
      headers: withHeaders(),
    },
  );

  return data as RecordDto;
};

export const makeUrgentRecord = async <T = any>(
  id: string,
): Promise<RecordDto> => {
  const { data } = await recordAxiosInstance.patch<T>(
    `/records/make-urgent/${id}`,
    {
      isUrgent: true,
    },
    {
      headers: withHeaders(),
    },
  );

  return data as RecordDto;
};

export const unMakeUrgentRecord = async <T = any>(
  id: string,
): Promise<RecordDto> => {
  const { data } = await recordAxiosInstance.patch<T>(
    `/records/make-urgent/${id}`,
    {
      isUrgent: false,
    },
    {
      headers: withHeaders(),
    },
  );

  return data as RecordDto;
};

/**
 * PUT /records/:id
 * --------------------------------------------------
 * Update an existing record.
 */
export const updateRecord = async <T = any>(
  recordId: string,
  payload: T,
): Promise<RecordDto> => {
  const { data } = await recordAxiosInstance.put<T>(
    `/records/${recordId}`,
    payload,
    {
      headers: withHeaders(),
    },
  );

  return data as RecordDto;
};

export interface ApprovalDispatchData {
  stampId?: string;
  signatureId?: string;
  note?: string;
  recordPrefixId?: string;
}

export interface UpdateDelegationRecordPayload {
  id: string;
  endDate: Date;
  startDate: Date;
  positionId?: string;
  employeeId?: string;
  internalCC?: {
    unitId: string;
    positionId: string;
    type: "internal" | "external";
  }[];
  stampId?: string;
  signatureId?: string;
  language?: "en" | "am";
}

/**
 * POST /records/create-and-submit
 * --------------------------------------------------
 * Create a record and forward (submit) it in a single call.
 * Backend expects the record payload wrapped in `createDto`.
 */
export const createAndSubmitRecord = async <T = any>(
  payload: T,
): Promise<RecordDto> => {
  try {
    const { data } = await recordAxiosInstance.post(
      "/records/create-and-submit",
      { createDto: payload },
      { headers: withHeaders() },
    );
    return data as RecordDto;
  } catch (error: any) {
    const message =
      error?.response?.data?.message || "Failed to create and forward record";
    throw new Error(message);
  }
};

/**
 * POST /records/create-submit-and-send-to-ro
 * --------------------------------------------------
 * Create + submit + send-to-RO (approve) in a single call.
 * Backend expects: { createDto: <record>, submitDto: <approval> }
 */
export const createSubmitAndSendToRoRecord = async <T = any>(
  payload: T,
  approval: ApprovalDispatchData,
): Promise<RecordDto> => {
  try {
    const { data } = await recordAxiosInstance.post(
      "/records/create-submit-and-send-to-ro",
      { createDto: payload, submitDto: approval },
      { headers: withHeaders() },
    );
    return data as RecordDto;
  } catch (error: any) {
    const message =
      error?.response?.data?.message || "Failed to create and approve record";
    throw new Error(message);
  }
};

/**
 * PATCH /records/update-and-submit/{id}
 * --------------------------------------------------
 * Update a record and forward (submit) it in a single call.
 * Backend expects the record payload wrapped in `updateDto`.
 */
export const updateAndSubmitRecord = async <T = any>(
  recordId: string,
  payload: T,
): Promise<RecordDto> => {
  try {
    const { data } = await recordAxiosInstance.patch(
      `/records/update-and-submit/${recordId}`,
      { updateDto: payload },
      { headers: withHeaders() },
    );
    return data as RecordDto;
  } catch (error: any) {
    const message =
      error?.response?.data?.message || "Failed to update and forward record";
    throw new Error(message);
  }
};

export const updateDelegationRecord = async ({
  id,
  endDate,
  startDate,
  positionId,
  employeeId,
  internalCC,
  stampId,
  signatureId,
  language,
}: UpdateDelegationRecordPayload): Promise<void> => {
  await recordAxiosInstance.patch(
    `/records/delegation-record/${id}`,
    {
      to: endDate.toISOString(),
      from: startDate.toISOString(),
      positionId,
      employeePositionId: employeeId,
      cc: internalCC,
      stampId: stampId || "",
      signatureId: signatureId || "",
      locale: language || "am",
    },
    {
      headers: withHeaders(),
    },
  );
};

/**
 * PATCH /records/update-submit-and-send-to-ro/{id}
 * --------------------------------------------------
 * Update + submit + send-to-RO (approve) in a single call.
 * Backend expects: { updateDto: <record>, submitDto: <approval> }
 */
export const updateSubmitAndSendToRoRecord = async <T = any>(
  recordId: string,
  payload: T,
  approval: ApprovalDispatchData,
): Promise<RecordDto> => {
  try {
    const { data } = await recordAxiosInstance.patch(
      `/records/update-submit-and-send-to-ro/${recordId}`,
      { updateDto: payload, submitDto: approval },
      { headers: withHeaders() },
    );
    return data as RecordDto;
  } catch (error: any) {
    const message =
      error?.response?.data?.message || "Failed to update and approve record";
    throw new Error(message);
  }
};

/**
 * DELETE /records/:id
 * --------------------------------------------------
 * Delete a record.
 */
export const deleteRecord = async (recordId: string): Promise<void> => {
  await recordAxiosInstance.delete(`/records/${recordId}`, {
    headers: withHeaders(),
  });
};

export const directSubmitRecord = async ({
  recordId,
  signatureId,
}: {
  recordId: string;
  signatureId: string;
}): Promise<void> => {
  await recordAxiosInstance.patch(
    `/records/direct-submit/${recordId}`,
    { signatureId },
    {
      headers: withHeaders(),
    },
  );
};

/**
 * POST /records/create-and-submit-direct-record
 * --------------------------------------------------
 * Create and directly submit a direct record in a single call.
 * Backend expects the record payload wrapped in `createDto`.
 */
export const createAndSubmitDirectRecord = async <T = any>({
  payload,
  signatureId,
}: {
  payload: T;
  signatureId: string;
}): Promise<RecordDto> => {
  try {
    const { data } = await recordAxiosInstance.post(
      "/records/create-and-submit-direct-record",
      { createDto: payload, signatureId },
      { headers: withHeaders() },
    );
    return data as RecordDto;
  } catch (error: any) {
    const message =
      error?.response?.data?.message ||
      "Failed to create and send direct record";
    throw new Error(message);
  }
};

/**
 * PATCH /records/update-and-submit-direct-record/{id}
 * --------------------------------------------------
 * Update and directly submit a direct record in a single call.
 * Backend expects the record payload wrapped in `updateDto`.
 */
export const updateAndSubmitDirectRecord = async <T = any>(
  recordId: string,
  {
    payload,
    signatureId,
  }: {
    payload: T;
    signatureId: string;
  },
): Promise<RecordDto> => {
  try {
    const { data } = await recordAxiosInstance.patch(
      `/records/update-and-submit-direct-record/${recordId}`,
      { updateDto: payload, signatureId },
      { headers: withHeaders() },
    );
    return data as RecordDto;
  } catch (error: any) {
    const message =
      error?.response?.data?.message ||
      "Failed to update and send direct record";
    throw new Error(message);
  }
};

export const directDispatchRecord = async ({
  recordId,
  signatureId,
}: {
  recordId: string;
  signatureId: string;
}): Promise<void> => {
  try {
    await recordAxiosInstance.patch(
      "/outgoing-instances/direct-dispatch",
      { recordId, signatureId },
      {
        headers: withHeaders(),
      },
    );
  } catch (error: any) {
    const message =
      error?.response?.data?.message || "Failed to dispatch direct record";
    throw new Error(message);
  }
};

export const lockRecord = async (
  recordId: string,
  isLocked: boolean,
): Promise<void> => {
  try {
    await recordAxiosInstance.patch(
      `/records/make-locked/${recordId}`,
      { isLocked },
      {
        headers: withHeaders(),
      },
    );
  } catch (error: any) {
    const message =
      error?.response?.data?.message || "Failed to force dispatch record";
    throw new Error(message);
  }
};

export const forceDispatchCollaboratorRecord = async (
  recordId: string,
): Promise<void> => {
  try {
    await recordAxiosInstance.patch(
      "/record-collaborators/force-dispatch",
      { recordId },
      {
        headers: withHeaders(),
      },
    );
  } catch (error: any) {
    const message =
      error?.response?.data?.message || "Failed to force dispatch record";
    throw new Error(message);
  }
};
export const forceDispatchCollaboratorInternalMemoRecord = async (
  recordId: string,
): Promise<void> => {
  try {
    await recordAxiosInstance.patch(
      "/record-collaborators/force-send-to-ro",
      { recordId },
      {
        headers: withHeaders(),
      },
    );
  } catch (error: any) {
    const message =
      error?.response?.data?.message || "Failed to force dispatch record";
    throw new Error(message);
  }
};
export const softDeleteRecord = async (recordId: string): Promise<void> => {
  await recordAxiosInstance.delete(`/records/${recordId}`, {
    headers: withHeaders(),
  });
};

export const getAttachmentsById = async (id: any): Promise<any> => {
  const response = await recordAxiosInstance.get(`record-attachments/${id}`, {
    headers: withHeaders(),
  });
  return response.data;
};
export const getSealedAttachmentsById = async (id: any): Promise<any> => {
  const response = await recordAxiosInstance.get(
    `record-attachments/sealed/${id}`,
    {
      headers: withHeaders(),
    },
  );
  return response.data;
};

export const deleteAttachmentsById = async (id: any): Promise<void> => {
  await recordAxiosInstance.delete(`record-attachments/${id}`, {
    headers: withHeaders(),
  });
};

export const fetchRecordById = async (recordId: string): Promise<RecordDto> => {
  const { data } = await recordAxiosInstance.get(`records/${recordId}`, {
    headers: withHeaders(),
  });

  return data;
};

export const fetchRecordContentByRecordId = async (
  recordId: string,
): Promise<RecordContentByRecordIdResponse> => {
  const { data } = await recordAxiosInstance.get(
    `record-contents/by-record/${recordId}`,
    {
      headers: withHeaders(),
    },
  );

  return data;
};

export const fetchRecordInstanceById = async (
  recordId: string,
): Promise<RecordDto> => {
  const { data } = await recordAxiosInstance.get(
    `/incoming-instances/${recordId}/record`,
    {
      headers: withHeaders(),
    },
  );

  return data;
};

export const fetchDelegationRecordById = async (
  recordId: string,
): Promise<RecordDto> => {
  const { data } = await recordAxiosInstance.get(
    `/records/delegation-record/${recordId}`,
    {
      headers: withHeaders(),
    },
  );

  return data;
};

export interface DelegationCcEntry {
  unitId: string;
  positionId: string;
  type: "internal";
}

export interface UpdateDelegationDateRangePayload {
  from: string;
  to: string;
  cc: DelegationCcEntry[];
}

export const updateDelegationRecordDateRange = async (
  recordId: string,
  payload: UpdateDelegationDateRangePayload,
): Promise<void> => {
  await recordAxiosInstance.patch(
    `/records/delegation-record/${recordId}/date-range`,
    payload,
    {
      headers: withHeaders(),
    },
  );
};

export const verifyRecordById = async (
  recordId: string,
): Promise<RecordVerificationDto> => {
  const { data } = await recordAxiosInstance.get(
    `records/verify-record/${recordId}`,
    {
      headers: withHeaders(),
    },
  );

  return data;
};

export const fetchLetterById = async (recordId: string): Promise<any> => {
  const res = await recordAxiosInstance.get(`records/record-pdf/${recordId}`);
  return res.data;
}; //
export const fetchLetterPreview = async (recordId: string): Promise<any> => {
  const res = await recordAxiosInstance.get(`records/review-pdf/${recordId}`, {
    responseType: "arraybuffer",
    headers: withHeaders(),
  });
  return res.data;
}; // buffer draft adjustment stage

export const regeneratePdf = async (recordId: string): Promise<any> => {
  const res = await recordAxiosInstance.get(
    `records/regenerate-pdf/${recordId}`,
    {
      headers: withHeaders(),
    },
  );
  return res.data;
};

export const previewRecord = async (payload: any): Promise<ArrayBuffer> => {
  const { data } = await recordAxiosInstance.post(
    "records/preview-pdf",
    payload,
    {
      responseType: "arraybuffer",
      headers: withHeaders(),
    },
  );
  return data;
};

export const previewRecordPdf = async (payload: any): Promise<Blob> => {
  const arrayBuffer = await previewRecord(payload);
  return new Blob([arrayBuffer], { type: "application/pdf" });
};

export interface CanSkipLevelUpResponse {
  canSkipLevel: boolean;
}

export const canSkipLevelUp = async (): Promise<CanSkipLevelUpResponse> => {
  try {
    const { data } = await recordAxiosInstance.get(
      "/outgoing-instances/can-skip-level",
      {
        headers: withHeaders(),
      },
    );
    return {
      canSkipLevel: data.canSkipLevel === true || data.canSkipLevel === "true",
    };
  } catch (error) {
    console.error("Error checking canSkipLevelUp:", error);
    return { canSkipLevel: false };
  }
};

/**
 * POST /records/share-via-email/:id
 * --------------------------------------------------
 * Share a record via email to specified email address.
 */
// export const shareRecordViaEmail = async (
//   recordId: string,
//   email: string
// ): Promise<void> => {
//   try {
//     await recordAxiosInstance.post(
//       `/records/share-via-email/${recordId}`,
//       { email },
//       {
//         headers: withHeaders(),
//       }
//     );
//   } catch (error: unknown) {
//     const message =
//       error?.response?.data?.message || "Failed to share record via email";
//     throw new Error(message);
//   }
// };
