import axios from 'axios';
import base64js from 'base64-js';

import api from 'src/config/api';
import {
  CLOSED,
  FormStatus,
  FormStatsResponse,
  FormPaginationResponse,
  FormAttributes,
  FormChatsNotificationsResponse,
  FormSubmitData,
  AssignBulkBody,
  ReviewBulkBody,
} from 'src/types/forms';
import { getBlobUrl } from 'src/utils/files';

export const getFormsCompleted = (
  id,
  type,
  title,
  page = undefined,
  limit = undefined,
) =>
  api.get<FormPaginationResponse>(`/users/${id}/forms/?type=${type}`, {
    params: {
      page,
      limit,
      title,
    },
  });

export const getStatsForms = id =>
  api.get<FormStatsResponse>(`/users/${id}/forms/stats`);

export const getFormsAvailable = (type, title, page, limit = 20) =>
  api.get<FormPaginationResponse>(`/forms?type=${type}&status=ENABLED`, {
    params: {
      page,
      limit,
      title,
    },
  });

// TODO: cuando el back realice los cambios correspondientes se deberá volver
// a como estaban antes las funciones: getUnassignedForms, getPendingForms y getClosedForms
export const getUnassignedForms = async (query, page, limit = 20) => {
  const response = await api.get(
    `/chats/forms?type=FORM&approvalStatus=${FormStatus.UNASSIGNED}`,
    { params: { page, limit, q: query } },
  );

  return {
    ...response,
    data: response.data.items.map(elem => ({
      ...elem,
      approvalStatus: FormStatus.UNASSIGNED,
    })),
  };
};

export const getPendingForms = async (query, page, limit = 20) => {
  const response = await api.get(
    `/chats/forms?type=FORM&approvalStatus=${FormStatus.PENDING}`,
    { params: { page, limit, q: query } },
  );
  return {
    ...response,
    data: response.data.items.map(elem => ({
      ...elem,
      approvalStatus: FormStatus.PENDING,
    })),
  };
};

export const getClosedForms = async (query, page, limit = 20) => {
  const response = await api.get(
    `/chats/forms?type=FORM&approvalStatus=${CLOSED}`,
    { params: { page, limit, q: query } },
  );
  return {
    ...response,
    data: response.data.items.map(elem => ({
      ...elem,
      approvalStatus: CLOSED,
    })),
  };
};

export const getForm = id => api.get<FormAttributes>(`/forms/${id}`);

export const getFilledForm = async (userId, formId) =>
  api.get(`/users/${userId}/forms/${formId}`);

export const getFormAnswer = (templateId, answerId) =>
  api.get<FormAttributes>(`/forms/${templateId}/answers/${answerId}`);

export const assignForm = id => api.post(`/chats/forms/${id}/assignment`);

export const bulkAssign = (body: AssignBulkBody) =>
  api.post('/forms/requests/bulk-assignment', body);

export const bulkReview = (body: ReviewBulkBody) =>
  api.post('/forms/requests/bulk-review', body);

export const changeStatusForm = (id, body) =>
  api.put(`/chats/forms/${id}/status`, body);

// TODO: hablar con el back para que la respuesta de esto sea un Form asi actualizamos directamente la cache
export const assignApprovalWorkflow = (formId, stepId, body) =>
  api.put(
    `/forms/${formId}/approval-workflow/steps/${stepId}/responsible`,
    body,
  );

// TODO: hablar con el back para que la respuesta de esto sea un Form asi actualizamos directamente la cache
export const closeApprovalWorkflow = (formId, stepId, body) =>
  api.put(`/forms/${formId}/approval-workflow/steps/${stepId}/review`, body);

export const createForm = (id, body: FormSubmitData) =>
  api.post(`/forms/${id}`, body);

export const editForm = (templateId, answerId, body: FormSubmitData) =>
  api.put(`/forms/${templateId}/answers/${answerId}`, body);

export const uploadDigitalSignature = async (image, signedUrl) => {
  const binaryData = base64js.toByteArray(image);

  await axios.put(signedUrl, binaryData, {
    headers: {
      'Content-Type': 'image/png',
      'Content-Encoding': 'base64',
    },
  });

  return signedUrl.split('?')[0];
};

export const getApprovalWorkflow = formId =>
  api.get(`/forms/${formId}/approval-workflow`);

export const getFormCompletedPdf = (templateId, formId) =>
  api.get(`/forms/${templateId}/answers/${formId}/report`, {
    responseType: 'blob',
  });

export const getPdfFormAnswer = (templateId, formId) =>
  api.get(`/forms/${templateId}/answers/${formId}/pdf`, {
    responseType: 'blob',
  });

export const fetchFormCompletedPdfBlob = async (
  templateId,
  formId,
  isPdfForm = false,
) => {
  const downloadEndpoint = isPdfForm ? getPdfFormAnswer : getFormCompletedPdf;
  const response = await downloadEndpoint(templateId, formId);
  const blob = new Blob([response.data], { type: 'application/pdf' });
  const blobUrl = getBlobUrl(blob);

  return {
    blob,
    blobUrl,
  };
};

// Notifications
export const getFormChatsNotifications = () =>
  api.get<FormChatsNotificationsResponse>('red-bubbles/form-chats');

export const clearFormChatNotifications = (id: number | string) =>
  api.post(`red-bubbles/form-chats/${id}/clear`);

export const cancelFormAnswer = (formId: number, reason: string) =>
  api.post(`forms/${formId}/cancel`, { reason });
