import { mutationOptions } from '@tanstack/react-query';
import { getQueryClient } from '@/lib/query-client';
import { quotationDocumentKeys } from '@/features/crm/quotations/document/queries';
import {
  createQuotation,
  createQuotationAttachment,
  createQuotationCustomer,
  createQuotationFollowup,
  createQuotationItem,
  createQuotationRevision,
  createQuotationTopic,
  deleteQuotation,
  deleteQuotationAttachment,
  deleteQuotationCustomer,
  deleteQuotationFollowup,
  deleteQuotationItem,
  deleteQuotationTopic,
  updateQuotation,
  updateQuotationAttachment,
  updateQuotationCustomer,
  updateQuotationFollowup,
  updateQuotationItem,
  updateQuotationTopic
} from './service';
import { quotationKeys } from './queries';
import type {
  QuotationAttachmentMutationPayload,
  QuotationCustomerMutationPayload,
  QuotationFollowupMutationPayload,
  QuotationItemMutationPayload,
  QuotationMutationPayload,
  QuotationTopicMutationPayload
} from './types';

async function invalidateQuotationLists() {
  await getQueryClient().invalidateQueries({ queryKey: quotationKeys.lists() });
}

async function invalidateQuotationDetail(quotationId: string) {
  await getQueryClient().invalidateQueries({ queryKey: quotationKeys.detail(quotationId) });
}

async function invalidateQuotationDocumentQueries(quotationId: string) {
  await Promise.all([
    getQueryClient().invalidateQueries({ queryKey: quotationDocumentKeys.data(quotationId) }),
    getQueryClient().invalidateQueries({ queryKey: quotationDocumentKeys.preview(quotationId) })
  ]);
}

async function invalidateQuotationHeaderQueries(quotationId: string) {
  await Promise.all([
    invalidateQuotationLists(),
    invalidateQuotationDetail(quotationId),
    invalidateQuotationDocumentQueries(quotationId)
  ]);
}

async function invalidateQuotationItems(quotationId: string) {
  await getQueryClient().invalidateQueries({ queryKey: quotationKeys.items(quotationId) });
}

async function invalidateQuotationCustomers(quotationId: string) {
  await getQueryClient().invalidateQueries({ queryKey: quotationKeys.customers(quotationId) });
}

async function invalidateQuotationTopics(quotationId: string) {
  await getQueryClient().invalidateQueries({ queryKey: quotationKeys.topics(quotationId) });
}

async function invalidateQuotationFollowups(quotationId: string) {
  await getQueryClient().invalidateQueries({ queryKey: quotationKeys.followups(quotationId) });
}

async function invalidateQuotationAttachments(quotationId: string) {
  await getQueryClient().invalidateQueries({ queryKey: quotationKeys.attachments(quotationId) });
}

async function invalidateQuotationRevisions(quotationId: string) {
  await getQueryClient().invalidateQueries({ queryKey: quotationKeys.revisions(quotationId) });
}

async function removeQuotationDetailQueries(quotationId: string) {
  getQueryClient().removeQueries({ queryKey: quotationKeys.detail(quotationId) });
  getQueryClient().removeQueries({ queryKey: quotationKeys.items(quotationId) });
  getQueryClient().removeQueries({ queryKey: quotationKeys.customers(quotationId) });
  getQueryClient().removeQueries({ queryKey: quotationKeys.topics(quotationId) });
  getQueryClient().removeQueries({ queryKey: quotationKeys.followups(quotationId) });
  getQueryClient().removeQueries({ queryKey: quotationKeys.attachments(quotationId) });
  getQueryClient().removeQueries({ queryKey: quotationKeys.revisions(quotationId) });
  getQueryClient().removeQueries({ queryKey: quotationDocumentKeys.data(quotationId) });
  getQueryClient().removeQueries({ queryKey: quotationDocumentKeys.preview(quotationId) });
}

export const createQuotationMutation = mutationOptions({
  mutationFn: (data: QuotationMutationPayload) => createQuotation(data),
  onSettled: async (_data, error) => {
    if (!error) {
      await invalidateQuotationLists();
    }
  }
});

export const updateQuotationMutation = mutationOptions({
  mutationFn: ({ id, values }: { id: string; values: QuotationMutationPayload }) =>
    updateQuotation(id, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await invalidateQuotationHeaderQueries(variables.id);
    }
  }
});

export const deleteQuotationMutation = mutationOptions({
  mutationFn: (id: string) => deleteQuotation(id),
  onSettled: async (_data, error, id) => {
    if (!error) {
      await removeQuotationDetailQueries(id);
      await invalidateQuotationLists();
    }
  }
});

export const createQuotationItemMutation = mutationOptions({
  mutationFn: ({ quotationId, values }: { quotationId: string; values: QuotationItemMutationPayload }) =>
    createQuotationItem(quotationId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationItems(variables.quotationId),
        invalidateQuotationHeaderQueries(variables.quotationId)
      ]);
    }
  }
});

export const updateQuotationItemMutation = mutationOptions({
  mutationFn: ({
    quotationId,
    itemId,
    values
  }: {
    quotationId: string;
    itemId: string;
    values: QuotationItemMutationPayload;
  }) => updateQuotationItem(quotationId, itemId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationItems(variables.quotationId),
        invalidateQuotationHeaderQueries(variables.quotationId)
      ]);
    }
  }
});

export const deleteQuotationItemMutation = mutationOptions({
  mutationFn: ({ quotationId, itemId }: { quotationId: string; itemId: string }) =>
    deleteQuotationItem(quotationId, itemId),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationItems(variables.quotationId),
        invalidateQuotationHeaderQueries(variables.quotationId)
      ]);
    }
  }
});

export const createQuotationCustomerMutation = mutationOptions({
  mutationFn: ({
    quotationId,
    values
  }: {
    quotationId: string;
    values: QuotationCustomerMutationPayload;
  }) => createQuotationCustomer(quotationId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationCustomers(variables.quotationId),
        invalidateQuotationHeaderQueries(variables.quotationId)
      ]);
    }
  }
});

export const updateQuotationCustomerMutation = mutationOptions({
  mutationFn: ({
    quotationId,
    relationId,
    values
  }: {
    quotationId: string;
    relationId: string;
    values: QuotationCustomerMutationPayload;
  }) => updateQuotationCustomer(quotationId, relationId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationCustomers(variables.quotationId),
        invalidateQuotationHeaderQueries(variables.quotationId)
      ]);
    }
  }
});

export const deleteQuotationCustomerMutation = mutationOptions({
  mutationFn: ({ quotationId, relationId }: { quotationId: string; relationId: string }) =>
    deleteQuotationCustomer(quotationId, relationId),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationCustomers(variables.quotationId),
        invalidateQuotationHeaderQueries(variables.quotationId)
      ]);
    }
  }
});

export const createQuotationTopicMutation = mutationOptions({
  mutationFn: ({ quotationId, values }: { quotationId: string; values: QuotationTopicMutationPayload }) =>
    createQuotationTopic(quotationId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationTopics(variables.quotationId),
        invalidateQuotationDetail(variables.quotationId),
        invalidateQuotationDocumentQueries(variables.quotationId)
      ]);
    }
  }
});

export const updateQuotationTopicMutation = mutationOptions({
  mutationFn: ({ quotationId, values }: { quotationId: string; values: QuotationTopicMutationPayload }) =>
    updateQuotationTopic(quotationId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationTopics(variables.quotationId),
        invalidateQuotationDetail(variables.quotationId),
        invalidateQuotationDocumentQueries(variables.quotationId)
      ]);
    }
  }
});

export const deleteQuotationTopicMutation = mutationOptions({
  mutationFn: ({ quotationId, topicId }: { quotationId: string; topicId: string }) =>
    deleteQuotationTopic(quotationId, topicId),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationTopics(variables.quotationId),
        invalidateQuotationDetail(variables.quotationId),
        invalidateQuotationDocumentQueries(variables.quotationId)
      ]);
    }
  }
});

export const createQuotationFollowupMutation = mutationOptions({
  mutationFn: ({
    quotationId,
    values
  }: {
    quotationId: string;
    values: QuotationFollowupMutationPayload;
  }) => createQuotationFollowup(quotationId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationFollowups(variables.quotationId),
        invalidateQuotationDetail(variables.quotationId)
      ]);
    }
  }
});

export const updateQuotationFollowupMutation = mutationOptions({
  mutationFn: ({
    quotationId,
    values
  }: {
    quotationId: string;
    values: QuotationFollowupMutationPayload;
  }) => updateQuotationFollowup(quotationId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationFollowups(variables.quotationId),
        invalidateQuotationDetail(variables.quotationId)
      ]);
    }
  }
});

export const deleteQuotationFollowupMutation = mutationOptions({
  mutationFn: ({ quotationId, followupId }: { quotationId: string; followupId: string }) =>
    deleteQuotationFollowup(quotationId, followupId),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationFollowups(variables.quotationId),
        invalidateQuotationDetail(variables.quotationId)
      ]);
    }
  }
});

export const createQuotationAttachmentMutation = mutationOptions({
  mutationFn: ({
    quotationId,
    values
  }: {
    quotationId: string;
    values: QuotationAttachmentMutationPayload;
  }) => createQuotationAttachment(quotationId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationAttachments(variables.quotationId),
        invalidateQuotationDetail(variables.quotationId)
      ]);
    }
  }
});

export const updateQuotationAttachmentMutation = mutationOptions({
  mutationFn: ({
    quotationId,
    values
  }: {
    quotationId: string;
    values: QuotationAttachmentMutationPayload;
  }) => updateQuotationAttachment(quotationId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationAttachments(variables.quotationId),
        invalidateQuotationDetail(variables.quotationId)
      ]);
    }
  }
});

export const deleteQuotationAttachmentMutation = mutationOptions({
  mutationFn: ({ quotationId, attachmentId }: { quotationId: string; attachmentId: string }) =>
    deleteQuotationAttachment(quotationId, attachmentId),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationAttachments(variables.quotationId),
        invalidateQuotationDetail(variables.quotationId)
      ]);
    }
  }
});

export const createQuotationRevisionMutation = mutationOptions({
  mutationFn: ({
    quotationId,
    revisionRemark
  }: {
    quotationId: string;
    revisionRemark?: string;
  }) => createQuotationRevision(quotationId, revisionRemark),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateQuotationRevisions(variables.quotationId),
        invalidateQuotationHeaderQueries(variables.quotationId)
      ]);
    }
  }
});
