import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { emailDomainService } from "services";
import {
  PatchEmailDomainRequest,
  PostEmailDomainRequest,
  GetEmailDomainResponse,
} from "types/email-domains";
import { Maybe } from "yup/lib/types";
import { EmailDomainState } from "./types";

const CUSTOM_DOMAIN_QUERY_KEY = ["email-domain-setup"] as const;

function mapResponseData(
  response: Maybe<GetEmailDomainResponse>
): EmailDomainState {
  if (!response) {
    return { status: "empty" };
  }
  switch (response.status) {
    case "issue":
    case "pending":
    case "verified":
      return {
        status: response.status,
        value: {
          domain: response.domain.domain,
          senderName: response.domain.senderName,
          username: response.domain.username,
          dnsRecords: response.domainRecords.map((o) => ({
            host: o.host,
            type: o.type,
            value: o.data,
          })),
        },
      };
    default:
      throw new Error(`Status must be "issue", "pending", or "verified"`);
  }
}

export function useEmailDomainQuery() {
  const query = useQuery(
    CUSTOM_DOMAIN_QUERY_KEY,
    async (): Promise<EmailDomainState> => {
      const response = await emailDomainService.getEmailDomain();
      return mapResponseData(response);
    }
  );

  return query;
}

export function useCancelEmailDomainMutation() {
  const query = useQueryClient();
  const mutation = useMutation(async () => {
    const newvalue = await emailDomainService.deleteEmailDomain();
    query.setQueryData<EmailDomainState>(
      CUSTOM_DOMAIN_QUERY_KEY,
      mapResponseData(newvalue)
    );
  });

  return mutation;
}

export function useVerifyEmailDomainMutation() {
  const query = useQueryClient();
  const mutation = useMutation(async () => {
    const result = await emailDomainService.verifyEmailDomain();
    query.setQueryData<EmailDomainState>(
      CUSTOM_DOMAIN_QUERY_KEY,
      mapResponseData(result)
    );

    return result;
  });

  return mutation;
}

export function useRemoveEmailDomainMutation() {
  const query = useQueryClient();
  const mutation = useMutation(async () => {
    const newvalues = await emailDomainService.deleteEmailDomain();
    query.setQueryData<EmailDomainState>(
      CUSTOM_DOMAIN_QUERY_KEY,
      mapResponseData(newvalues)
    );
  });

  return mutation;
}

export function usePostDnsRecordsMutation() {
  const query = useQueryClient();
  const mutation = useMutation(async (data: PostEmailDomainRequest) => {
    const newvalues = await emailDomainService.postEmailDomain(data);
    query.setQueryData<EmailDomainState>(
      CUSTOM_DOMAIN_QUERY_KEY,
      mapResponseData(newvalues)
    );
  });

  return mutation;
}

export function usePatchDnsRecordsMutation() {
  const query = useQueryClient();
  const mutation = useMutation(async (data: PatchEmailDomainRequest) => {
    const newvalues = await emailDomainService.patchEmailDomain(data);
    query.setQueryData<EmailDomainState>(
      CUSTOM_DOMAIN_QUERY_KEY,
      mapResponseData(newvalues)
    );
  });
  return mutation;
}
