import { QuestionKeys } from "@/pages/IntegrationsPage/IntegrationsModal/Amo/types";
import { makeRequest } from "@frontend/kitui";
import { useToken } from "@frontend/kitui";
import { parseAxiosError } from "@utils/parse-error";
import useSWR from "swr";

export type PaginationRequest = {
  page: number;
  size: number;
};

const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz/amocrm`;

// получение информации об аккаунте

export type AccountResponse = {
  id: number;
  accountID: string;
  amoID: number;
  name: string;
  deleted: boolean;
  createdAt: string;
  subdomain: string;
  country: string;
  driveURL: string;
  stale: boolean;
};

export const getAccount = async (): Promise<[AccountResponse | null, string?]> => {
  try {
    const response = await makeRequest<void, AccountResponse>({
      method: "GET",
      url: `${API_URL}/account`,
      useToken: true,
    });
    return [response];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, ""];
    // return [null, `Не удалось получить информацию об аккаунте. ${error}`];
  }
};

export function useAmoAccount() {
  const token = useToken();

  return useSWR(token ? "amoAccount" : null, () =>
    makeRequest<void, AccountResponse>({
      method: "GET",
      url: `${API_URL}/account`,
      useToken: true,
    })
  );
}

// подключить Amo

export const connectAmo = async (): Promise<[string | null, string?]> => {
  try {
    const response = await makeRequest<void, { link: string }>({
      method: "POST",
      url: `${API_URL}/account`,
      useToken: true,
      withCredentials: true,
    });
    return [response.link];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Не удалось подключить аккаунт. ${error}`];
  }
};

// получение токена

export type TokenPair = {
  accessToken: string;
  refreshToken: string;
};

export const getTokens = async (): Promise<[TokenPair | null, string?]> => {
  try {
    const response = await makeRequest<void, TokenPair>({
      method: "GET",
      url: `${API_URL}/webhook/create`,
      useToken: true,
    });
    return [response];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Failed to get tokens. ${error}`];
  }
};

//получение списка тегов

export type Tag = {
  ID: number;
  AmoID: number;
  AccountID: number;
  Entity: string;
  Name: string;
  Color: string;
  Deleted: boolean;
  CreatedAt: number;
};

export type TagsResponse = {
  count: number;
  items: Tag[];
};

export const getTags = async ({ page, size }: PaginationRequest): Promise<[TagsResponse | null, string?]> => {
  try {
    const tagsResponse = await makeRequest<PaginationRequest, TagsResponse>({
      method: "GET",
      url: `${API_URL}/tags?page=${page}&size=${size}`,
    });
    return [tagsResponse];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Не удалось получить список тегов. ${error}`];
  }
};

//получение списка пользователей

export type User = {
  id: number;
  amoID: number;
  name: string;
  email: string;
  role: number;
  group: number;
  deleted: boolean;
  createdAt: string;
  amoUserID: number;

  // Subdomain: string;
  // AccountID: string;
};

export type UsersResponse = {
  count: number;
  items: User[];
};

export const getUsers = async ({ page, size }: PaginationRequest): Promise<[UsersResponse | null, string?]> => {
  try {
    const usersResponse = await makeRequest<PaginationRequest, UsersResponse>({
      method: "GET",
      url: `${API_URL}/users?page=${page}&size=${size}`,
    });
    return [usersResponse];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Не удалось получить список пользователей. ${error}`];
  }
};

//получение списка шагов

export type Step = {
  ID: number;
  AmoID: number;
  PipelineID: number;
  AccountID: number;
  Name: string;
  Color: string;
  Deleted: boolean;
  CreatedAt: number;
};

export type StepsResponse = {
  count: number;
  items: Step[];
};

export const getSteps = async ({
  page,
  size,
  pipelineId,
}: PaginationRequest & { pipelineId: number }): Promise<[StepsResponse | null, string?]> => {
  try {
    const stepsResponse = await makeRequest<PaginationRequest & { pipelineId: number }, StepsResponse>({
      method: "GET",
      url: `${API_URL}/steps?page=${page}&size=${size}&pipelineID=${pipelineId}`,
    });
    return [stepsResponse];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Не удалось получить список шагов. ${error}`];
  }
};

//получение списка воронок

export type Pipeline = {
  ID: number;
  AmoID: number;
  AccountID: number;
  Name: string;
  IsArchive: boolean;
  Deleted: boolean;
  CreatedAt: number;
};

export type PipelinesResponse = {
  count: number;
  items: Pipeline[];
};

export const getPipelines = async ({ page, size }: PaginationRequest): Promise<[PipelinesResponse | null, string?]> => {
  try {
    const pipelinesResponse = await makeRequest<PaginationRequest, PipelinesResponse>({
      method: "GET",
      url: `${API_URL}/pipelines?page=${page}&size=${size}`,
    });
    return [pipelinesResponse];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Не удалось получить список воронок. ${error}`];
  }
};

//получение настроек интеграции
export type QuestionID = Record<string, number>;

export type IntegrationRules = {
  PipelineID: number;
  StepID: number;
  PerformerID?: number;
  FieldsRule: FieldsRule;
  TagsToAdd: {
    Lead: number[] | null;
    Contact: number[] | null;
    Company: number[] | null;
    Customer: number[] | null;
  };
};
export type FieldsRule = Record<Partial<QuestionKeys>, null | [{ QuestionID: QuestionID }]>;

export const getIntegrationRules = async (quizID: string): Promise<[IntegrationRules | null, string?]> => {
  try {
    const settingsResponse = await makeRequest<void, IntegrationRules>({
      method: "GET",
      url: `${API_URL}/rules/${quizID}`,
    });
    return [settingsResponse || null];
  } catch (nativeError) {
    if (nativeError.response.status === 404) return [null, "first"];
    const [error] = parseAxiosError(nativeError);
    return [null, `Не удалось получить настройки интеграции. ${error}`];
  }
};

//обновление настроек интеграции

export type IntegrationRulesUpdate = {
  PerformerID: number;
  PipelineID: number;
  StepID: number;
  Utms: number[];
  FieldsRule: {
    Lead: { QuestionID: number }[];
    Contact: { ContactRuleMap: string }[];
    Company: { QuestionID: number }[];
    Customer: { QuestionID: number }[];
  };
};

export const setIntegrationRules = async (
  quizID: string,
  settings: IntegrationRulesUpdate
): Promise<[string | null, string?]> => {
  try {
    const updateResponse = await makeRequest<IntegrationRulesUpdate, string>({
      method: "POST",
      url: `${API_URL}/rules/${quizID}`,
      body: settings,
    });
    return [updateResponse];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Failed to update integration settings. ${error}`];
  }
};
export const updateIntegrationRules = async (
  quizID: string,
  settings: IntegrationRulesUpdate
): Promise<[string | null, string?]> => {
  try {
    const updateResponse = await makeRequest<IntegrationRulesUpdate, string>({
      method: "PATCH",
      url: `${API_URL}/rules/${quizID}`,
      body: settings,
    });
    return [updateResponse];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Failed to update integration settings. ${error}`];
  }
};

// Получение кастомных полей

export type CustomField = {
  ID: number;
  AmoID: number;
  Code: string;
  AccountID: number;
  Name: string;
  EntityType: string;
  Type: string;
  Deleted: boolean;
  CreatedAt: number;
};
export type Field = {
  ID: number;
  AmoID: number;
  Code: string;
  AccountID: number;
  Name: string;
  Entity: string;
  Type: string;
  Deleted: boolean;
  CreatedAt: number;
};

export type CustomFieldsResponse = {
  count: number;
  items: CustomField[];
};
export type FieldsResponse = {
  count: number;
  items: Field[];
};

export const getCustomFields = async (
  pagination: PaginationRequest
): Promise<[CustomFieldsResponse | null, string?]> => {
  try {
    const customFieldsResponse = await makeRequest<PaginationRequest, CustomFieldsResponse>({
      method: "GET",
      url: `${API_URL}/fields?page=${pagination.page}&size=${pagination.size}`,
    });
    return [customFieldsResponse];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Не удалось получить список кастомных полей. ${error}`];
  }
};

//Отвязать аккаунт амо от публикации

export const removeAmoAccount = async (): Promise<[void | null, string?]> => {
  try {
    await makeRequest<void>({
      method: "DELETE",
      url: `${API_URL}/account`,
    });
    return [null, ""];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Не удалось отвязать аккаунт. ${error}`];
  }
};


export const getFields = async (pagination: PaginationRequest): Promise<[FieldsResponse | null, string?]> => {
  try {
    const fieldsResponse = await makeRequest<PaginationRequest, FieldsResponse>({
      method: "GET",
      url: `${API_URL}/fields?page=${pagination.page}&size=${pagination.size}`,
    });
    return [fieldsResponse, ""];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);
    return [null, `Не удалось получить список полей. ${error}`];
  }
};
