// ============================================================
//  CRM – React Query Hooks
// ============================================================

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import {
  contactsApi,
  dealsApi,
  forecastApi,
  pipelinesApi,
  activitiesApi,
  companiesApi,
  industriesApi,
  accountTypesApi,
  relationshipTypesApi,
  companyRelationshipsApi,
  usersApi,
  lexwareContactsApi,
  lexwareVouchersApi,
  tradeEventsApi,
  ownersApi,
  customFieldsApi,
  importApi,
  enrichmentApi,
  contractsApi,
  contractFilesApi,
  integrationsApi,
  graphApi,
  office365Api,
  dealTypesApi,
} from './api';
import type {
  ContactsQueryParams,
  DealsQueryParams,
  ActivitiesQueryParams,
  CreateContactPayload,
  UpdateContactPayload,
  CreateDealPayload,
  UpdateDealPayload,
  CreatePipelinePayload,
  UpdatePipelinePayload,
  CreateStagePayload,
  UpdateStagePayload,
  CreateActivityPayload,
  UpdateActivityPayload,
  CompaniesQueryParams,
  CreateCompanyPayload,
  UpdateCompanyPayload,
  CreateIndustryPayload,
  UpdateIndustryPayload,
  CreateAccountTypePayload,
  UpdateAccountTypePayload,
  CreateRelationshipTypePayload,
  UpdateRelationshipTypePayload,
  CreateDealTypePayload,
  UpdateDealTypePayload,
  CreateCompanyRelationshipPayload,
  LexwareContactSearchParams,
  LexwareVouchersQueryParams,
  CreateTradeEventPayload,
  UpdateTradeEventPayload,
  AddOwnerPayload,
  CustomFieldEntityType,
  CreateCustomFieldDefPayload,
  UpdateCustomFieldDefPayload,
  SetCustomFieldValuesPayload,
  ForecastPeriod,
  ImportEntityType,
  ImportExecuteRequest,
  ContractsQueryParams,
  CreateContractPayload,
  UpdateContractPayload,
} from './types';

// --- Query Key Factory ---

export const crmKeys = {
  contacts: {
    all: ['crm', 'contacts'] as const,
    list: (params: ContactsQueryParams) =>
      ['crm', 'contacts', 'list', params] as const,
    detail: (id: string) => ['crm', 'contacts', 'detail', id] as const,
    byCompany: (companyId: string) =>
      ['crm', 'contacts', 'byCompany', companyId] as const,
  },
  deals: {
    all: ['crm', 'deals'] as const,
    list: (params: DealsQueryParams) =>
      ['crm', 'deals', 'list', params] as const,
    detail: (id: string) => ['crm', 'deals', 'detail', id] as const,
    forecast: (pipelineId?: string, period?: ForecastPeriod) =>
      ['crm', 'deals', 'forecast', pipelineId, period] as const,
  },
  pipelines: {
    all: ['crm', 'pipelines'] as const,
    list: () => ['crm', 'pipelines', 'list'] as const,
    detail: (id: string) => ['crm', 'pipelines', 'detail', id] as const,
  },
  activities: {
    all: ['crm', 'activities'] as const,
    list: (params: ActivitiesQueryParams) =>
      ['crm', 'activities', 'list', params] as const,
    detail: (id: string) => ['crm', 'activities', 'detail', id] as const,
  },
  companies: {
    all: ['crm', 'companies'] as const,
    list: (params: CompaniesQueryParams) =>
      ['crm', 'companies', 'list', params] as const,
    detail: (id: string) => ['crm', 'companies', 'detail', id] as const,
  },
  industries: {
    all: ['crm', 'industries'] as const,
    list: () => ['crm', 'industries', 'list'] as const,
  },
  accountTypes: {
    all: ['crm', 'accountTypes'] as const,
    list: () => ['crm', 'accountTypes', 'list'] as const,
  },
  relationshipTypes: {
    all: ['crm', 'relationshipTypes'] as const,
    list: () => ['crm', 'relationshipTypes', 'list'] as const,
  },
  dealTypes: {
    all: ['crm', 'dealTypes'] as const,
    list: () => ['crm', 'dealTypes', 'list'] as const,
  },
  companyRelationships: {
    all: ['crm', 'companyRelationships'] as const,
    list: (companyId: string) =>
      ['crm', 'companyRelationships', 'list', companyId] as const,
  },
  users: {
    all: ['crm', 'users'] as const,
    list: () => ['crm', 'users', 'list'] as const,
  },
  tradeEvents: {
    all: ['crm', 'tradeEvents'] as const,
    list: () => ['crm', 'tradeEvents', 'list'] as const,
    active: () => ['crm', 'tradeEvents', 'active'] as const,
    detail: (id: string) => ['crm', 'tradeEvents', 'detail', id] as const,
  },
  customFields: {
    all: ['crm', 'customFields'] as const,
    defs: (entityType?: CustomFieldEntityType) =>
      ['crm', 'customFields', 'defs', entityType] as const,
    values: (entityId: string) =>
      ['crm', 'customFields', 'values', entityId] as const,
  },
  lexware: {
    all: ['crm', 'lexware'] as const,
    contactSearch: (params: LexwareContactSearchParams) =>
      ['crm', 'lexware', 'contacts', 'search', params] as const,
    contactList: (params: LexwareContactSearchParams) =>
      ['crm', 'lexware', 'contacts', 'list', params] as const,
    vouchersCompany: (companyId: string, params?: LexwareVouchersQueryParams) =>
      ['crm', 'lexware', 'vouchers', 'company', companyId, params] as const,
    vouchersContact: (contactId: string, params?: LexwareVouchersQueryParams) =>
      ['crm', 'lexware', 'vouchers', 'contact', contactId, params] as const,
    vouchersDeal: (dealId: string) =>
      ['crm', 'lexware', 'vouchers', 'deal', dealId] as const,
  },
  enrichment: {
    config: () => ['crm', 'enrichment', 'config'] as const,
  },
  contracts: {
    all: ['crm', 'contracts'] as const,
    list: (companyId: string, params?: ContractsQueryParams) =>
      ['crm', 'contracts', 'list', companyId, params] as const,
  },
  contractFiles: {
    all: ['crm', 'contractFiles'] as const,
    list: (companyId: string, contractId: string) =>
      ['crm', 'contractFiles', 'list', companyId, contractId] as const,
  },
};

// ============================================================
//  Contacts
// ============================================================

export function useContacts(params: ContactsQueryParams) {
  return useQuery({
    queryKey: crmKeys.contacts.list(params),
    queryFn: () => contactsApi.list(params),
  });
}

export function useContact(id: string) {
  return useQuery({
    queryKey: crmKeys.contacts.detail(id),
    queryFn: () => contactsApi.getById(id),
    enabled: !!id,
  });
}

export function useCreateContact() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateContactPayload) => contactsApi.create(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

export function useUpdateContact() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateContactPayload }) =>
      contactsApi.update(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

export function useDeleteContact() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => contactsApi.delete(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

/**
 * Lazy-load contacts for a specific company (expandable rows).
 * Only fetches when enabled is true (i.e., the row is expanded).
 */
export function useCompanyContacts(companyId: string, enabled: boolean) {
  return useQuery({
    queryKey: crmKeys.contacts.byCompany(companyId),
    queryFn: () =>
      contactsApi.list({
        companyId,
        pageSize: 50,
        sort: 'lastName',
        order: 'asc',
      }),
    enabled: enabled && !!companyId,
    staleTime: 2 * 60 * 1000,
  });
}

// ============================================================
//  Deals
// ============================================================

export function useDeals(params: DealsQueryParams) {
  return useQuery({
    queryKey: crmKeys.deals.list(params),
    queryFn: () => dealsApi.list(params),
  });
}

export function useDeal(id: string) {
  return useQuery({
    queryKey: crmKeys.deals.detail(id),
    queryFn: () => dealsApi.getById(id),
    enabled: !!id,
  });
}

export function useCreateDeal() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateDealPayload) => dealsApi.create(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.deals.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

export function useUpdateDeal() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateDealPayload }) =>
      dealsApi.update(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.deals.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

export function useDeleteDeal() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => dealsApi.delete(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.deals.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

// ============================================================
//  Pipelines
// ============================================================

export function usePipelines() {
  return useQuery({
    queryKey: crmKeys.pipelines.list(),
    queryFn: () => pipelinesApi.list(),
    staleTime: 10 * 60 * 1000, // Pipelines aendern sich selten
  });
}

export function usePipeline(id: string) {
  return useQuery({
    queryKey: crmKeys.pipelines.detail(id),
    queryFn: () => pipelinesApi.getById(id),
    enabled: !!id,
  });
}

export function useCreatePipeline() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreatePipelinePayload) => pipelinesApi.create(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.pipelines.all });
    },
  });
}

export function useUpdatePipeline() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      id,
      data,
    }: {
      id: string;
      data: UpdatePipelinePayload;
    }) => pipelinesApi.update(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.pipelines.all });
    },
  });
}

export function useDeletePipeline() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => pipelinesApi.delete(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.pipelines.all });
    },
  });
}

export function useUpdateStage() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      pipelineId,
      stageId,
      data,
    }: {
      pipelineId: string;
      stageId: string;
      data: UpdateStagePayload;
    }) => pipelinesApi.updateStage(pipelineId, stageId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.pipelines.all });
    },
  });
}

export function useAddStage() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      pipelineId,
      data,
    }: {
      pipelineId: string;
      data: CreateStagePayload;
    }) => pipelinesApi.addStage(pipelineId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.pipelines.all });
    },
  });
}

export function useRemoveStage() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      pipelineId,
      stageId,
    }: {
      pipelineId: string;
      stageId: string;
    }) => pipelinesApi.removeStage(pipelineId, stageId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.pipelines.all });
    },
  });
}

// ============================================================
//  Activities
// ============================================================

export function useActivities(params: ActivitiesQueryParams) {
  return useQuery({
    queryKey: crmKeys.activities.list(params),
    queryFn: () => activitiesApi.list(params),
  });
}

export function useCreateActivity() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateActivityPayload) => activitiesApi.create(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.activities.all });
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
    },
  });
}

export function useUpdateActivity() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      id,
      data,
    }: {
      id: string;
      data: UpdateActivityPayload;
    }) => activitiesApi.update(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.activities.all });
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
    },
  });
}

export function useDeleteActivity() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => activitiesApi.delete(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.activities.all });
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
    },
  });
}

// ============================================================
//  Companies
// ============================================================

export function useCompanies(params: CompaniesQueryParams) {
  return useQuery({
    queryKey: crmKeys.companies.list(params),
    queryFn: () => companiesApi.list(params),
  });
}

export function useCompany(id: string) {
  return useQuery({
    queryKey: crmKeys.companies.detail(id),
    queryFn: () => companiesApi.getById(id),
    enabled: !!id,
  });
}

export function useCreateCompany() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateCompanyPayload) => companiesApi.create(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

export function useUpdateCompany() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateCompanyPayload }) =>
      companiesApi.update(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

export function useDeleteCompany() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => companiesApi.delete(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

// ============================================================
//  Industries
// ============================================================

export function useIndustries() {
  return useQuery({
    queryKey: crmKeys.industries.list(),
    queryFn: () => industriesApi.list(),
    staleTime: 10 * 60 * 1000,
  });
}

export function useCreateIndustry() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateIndustryPayload) => industriesApi.create(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.industries.all });
    },
  });
}

export function useUpdateIndustry() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateIndustryPayload }) =>
      industriesApi.update(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.industries.all });
    },
  });
}

export function useDeleteIndustry() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => industriesApi.delete(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.industries.all });
    },
  });
}

// ============================================================
//  Account Types
// ============================================================

export function useAccountTypes() {
  return useQuery({
    queryKey: crmKeys.accountTypes.list(),
    queryFn: () => accountTypesApi.list(),
    staleTime: 10 * 60 * 1000,
  });
}

export function useCreateAccountType() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateAccountTypePayload) =>
      accountTypesApi.create(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.accountTypes.all });
    },
  });
}

export function useUpdateAccountType() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      id,
      data,
    }: {
      id: string;
      data: UpdateAccountTypePayload;
    }) => accountTypesApi.update(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.accountTypes.all });
    },
  });
}

export function useDeleteAccountType() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => accountTypesApi.delete(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.accountTypes.all });
    },
  });
}

// ============================================================
//  Relationship Types
// ============================================================

export function useRelationshipTypes() {
  return useQuery({
    queryKey: crmKeys.relationshipTypes.list(),
    queryFn: () => relationshipTypesApi.list(),
    staleTime: 10 * 60 * 1000,
  });
}

export function useCreateRelationshipType() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateRelationshipTypePayload) =>
      relationshipTypesApi.create(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.relationshipTypes.all });
    },
  });
}

export function useUpdateRelationshipType() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      id,
      data,
    }: {
      id: string;
      data: UpdateRelationshipTypePayload;
    }) => relationshipTypesApi.update(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.relationshipTypes.all });
    },
  });
}

export function useDeleteRelationshipType() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => relationshipTypesApi.delete(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.relationshipTypes.all });
    },
  });
}

// ============================================================
//  Deal Types (Vorgangsart)
// ============================================================

export function useDealTypes() {
  return useQuery({
    queryKey: crmKeys.dealTypes.list(),
    queryFn: () => dealTypesApi.list(),
    staleTime: 10 * 60 * 1000,
  });
}

export function useCreateDealType() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateDealTypePayload) => dealTypesApi.create(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.dealTypes.all });
    },
  });
}

export function useUpdateDealType() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateDealTypePayload }) =>
      dealTypesApi.update(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.dealTypes.all });
    },
  });
}

export function useDeleteDealType() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => dealTypesApi.delete(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.dealTypes.all });
    },
  });
}

// ============================================================
//  Company Relationships
// ============================================================

export function useCompanyRelationships(companyId: string) {
  return useQuery({
    queryKey: crmKeys.companyRelationships.list(companyId),
    queryFn: () => companyRelationshipsApi.list(companyId),
    enabled: !!companyId,
  });
}

export function useCreateCompanyRelationship() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      companyId,
      data,
    }: {
      companyId: string;
      data: CreateCompanyRelationshipPayload;
    }) => companyRelationshipsApi.create(companyId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companyRelationships.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

export function useDeleteCompanyRelationship() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      companyId,
      relationshipId,
    }: {
      companyId: string;
      relationshipId: string;
    }) => companyRelationshipsApi.delete(companyId, relationshipId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companyRelationships.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

// ============================================================
//  Tenant Users
// ============================================================

export function useTenantUsers() {
  return useQuery({
    queryKey: crmKeys.users.list(),
    queryFn: () => usersApi.list(),
    staleTime: 10 * 60 * 1000,
  });
}

// ============================================================
//  Company Activities (Aggregated Feed)
// ============================================================

export function useCompanyActivities(
  companyId: string,
  params: Omit<ActivitiesQueryParams, 'companyId' | 'includeContacts'> = {},
) {
  const fullParams: ActivitiesQueryParams = {
    ...params,
    companyId,
    includeContacts: true,
    pageSize: params.pageSize ?? 50,
  };
  return useQuery({
    queryKey: crmKeys.activities.list(fullParams),
    queryFn: () => activitiesApi.list(fullParams),
    enabled: !!companyId,
  });
}

// ============================================================
//  Lexware Office — Contacts
// ============================================================

export function useLexwareContactSearch(
  params: LexwareContactSearchParams,
  enabled = true,
) {
  return useQuery({
    queryKey: crmKeys.lexware.contactSearch(params),
    queryFn: () => lexwareContactsApi.search(params),
    enabled: enabled && !!(params.name || params.email),
  });
}

/** Fetch Lexware contacts (paginated, no search filter required) */
export function useLexwareContacts(
  params: LexwareContactSearchParams = {},
  enabled = true,
) {
  return useQuery({
    queryKey: crmKeys.lexware.contactList(params),
    queryFn: () => lexwareContactsApi.search(params),
    enabled,
  });
}

export function useLinkLexwareCompany() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: { lexwareContactId: string; companyId: string }) =>
      lexwareContactsApi.linkCompany(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
      qc.invalidateQueries({ queryKey: crmKeys.lexware.all });
    },
  });
}

export function useLinkLexwareContact() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: { lexwareContactId: string; contactId: string }) =>
      lexwareContactsApi.linkContact(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
      qc.invalidateQueries({ queryKey: crmKeys.lexware.all });
    },
  });
}

export function useUnlinkLexwareCompany() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (companyId: string) =>
      lexwareContactsApi.unlinkCompany(companyId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
      qc.invalidateQueries({ queryKey: crmKeys.lexware.all });
    },
  });
}

export function useUnlinkLexwareContact() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (contactId: string) =>
      lexwareContactsApi.unlinkContact(contactId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
      qc.invalidateQueries({ queryKey: crmKeys.lexware.all });
    },
  });
}

export function usePushToLexware() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      entityType,
      entityId,
    }: {
      entityType: 'company' | 'contact';
      entityId: string;
    }) => lexwareContactsApi.push(entityType, entityId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
    },
  });
}

export function useSyncFromLexware() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      entityType,
      entityId,
    }: {
      entityType: 'company' | 'contact';
      entityId: string;
    }) => lexwareContactsApi.sync(entityType, entityId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
    },
  });
}

export function useImportLexwareAsCompany() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: { lexwareContactId: string }) =>
      lexwareContactsApi.importCompany(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
      qc.invalidateQueries({ queryKey: crmKeys.lexware.all });
    },
  });
}

export function useImportLexwareAsContact() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: { lexwareContactId: string }) =>
      lexwareContactsApi.importContact(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
      qc.invalidateQueries({ queryKey: crmKeys.lexware.all });
    },
  });
}

// ============================================================
//  Lexware Office — Vouchers
// ============================================================

export function useCompanyVouchers(
  companyId: string,
  params?: LexwareVouchersQueryParams,
) {
  return useQuery({
    queryKey: crmKeys.lexware.vouchersCompany(companyId, params),
    queryFn: () => lexwareVouchersApi.getForCompany(companyId, params),
    enabled: !!companyId,
  });
}

export function useContactVouchers(
  contactId: string,
  params?: LexwareVouchersQueryParams,
) {
  return useQuery({
    queryKey: crmKeys.lexware.vouchersContact(contactId, params),
    queryFn: () => lexwareVouchersApi.getForContact(contactId, params),
    enabled: !!contactId,
  });
}

export function useDealVouchers(dealId: string) {
  return useQuery({
    queryKey: crmKeys.lexware.vouchersDeal(dealId),
    queryFn: () => lexwareVouchersApi.getForDeal(dealId),
    enabled: !!dealId,
  });
}

export function useLinkVoucherToDeal() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ dealId, voucherId }: { dealId: string; voucherId: string }) =>
      lexwareVouchersApi.linkToDeal(dealId, voucherId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.lexware.all });
      qc.invalidateQueries({ queryKey: crmKeys.deals.all });
    },
  });
}

export function useUnlinkVoucherFromDeal() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ dealId, voucherId }: { dealId: string; voucherId: string }) =>
      lexwareVouchersApi.unlinkFromDeal(dealId, voucherId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.lexware.all });
      qc.invalidateQueries({ queryKey: crmKeys.deals.all });
    },
  });
}

export function useRefreshCompanyVouchers() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (companyId: string) =>
      lexwareVouchersApi.refreshCompany(companyId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.lexware.all });
    },
  });
}

export function useRefreshContactVouchers() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (contactId: string) =>
      lexwareVouchersApi.refreshContact(contactId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.lexware.all });
    },
  });
}

// ============================================================
//  Trade Events (Messe-Timer)
// ============================================================

export function useTradeEvents() {
  return useQuery({
    queryKey: crmKeys.tradeEvents.list(),
    queryFn: () => tradeEventsApi.list(),
  });
}

export function useActiveTradeEvents() {
  return useQuery({
    queryKey: crmKeys.tradeEvents.active(),
    queryFn: () => tradeEventsApi.listActive(),
  });
}

export function useCreateTradeEvent() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateTradeEventPayload) =>
      tradeEventsApi.create(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.tradeEvents.all });
    },
  });
}

export function useUpdateTradeEvent() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateTradeEventPayload }) =>
      tradeEventsApi.update(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.tradeEvents.all });
    },
  });
}

export function useDeleteTradeEvent() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => tradeEventsApi.delete(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.tradeEvents.all });
    },
  });
}

// ============================================================
//  Owners (Contact, Company, Deal)
// ============================================================

export function useAddContactOwner() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ contactId, data }: { contactId: string; data: AddOwnerPayload }) =>
      ownersApi.addContactOwner(contactId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
    },
  });
}

export function useRemoveContactOwner() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ contactId, userId }: { contactId: string; userId: string }) =>
      ownersApi.removeContactOwner(contactId, userId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
    },
  });
}

export function useAddCompanyOwner() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ companyId, data }: { companyId: string; data: AddOwnerPayload }) =>
      ownersApi.addCompanyOwner(companyId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

export function useRemoveCompanyOwner() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ companyId, userId }: { companyId: string; userId: string }) =>
      ownersApi.removeCompanyOwner(companyId, userId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

export function useAddDealOwner() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ dealId, data }: { dealId: string; data: AddOwnerPayload }) =>
      ownersApi.addDealOwner(dealId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.deals.all });
    },
  });
}

export function useRemoveDealOwner() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ dealId, userId }: { dealId: string; userId: string }) =>
      ownersApi.removeDealOwner(dealId, userId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.deals.all });
    },
  });
}

// ============================================================
//  Custom Fields (Phase 2.1)
// ============================================================

export function useCustomFieldDefs(entityType?: CustomFieldEntityType) {
  return useQuery({
    queryKey: crmKeys.customFields.defs(entityType),
    queryFn: () => customFieldsApi.listDefs(entityType),
    staleTime: 5 * 60 * 1000,
  });
}

export function useCreateCustomFieldDef() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateCustomFieldDefPayload) =>
      customFieldsApi.createDef(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.customFields.all });
    },
  });
}

export function useUpdateCustomFieldDef() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateCustomFieldDefPayload }) =>
      customFieldsApi.updateDef(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.customFields.all });
    },
  });
}

export function useDeleteCustomFieldDef() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => customFieldsApi.deleteDef(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.customFields.all });
      // Invalidate entities too since their customFields arrays change
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
      qc.invalidateQueries({ queryKey: crmKeys.deals.all });
    },
  });
}

export function useCustomFieldValues(entityId: string) {
  return useQuery({
    queryKey: crmKeys.customFields.values(entityId),
    queryFn: () => customFieldsApi.getValues(entityId),
    enabled: !!entityId,
  });
}

export function useSetCustomFieldValues() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      entityId,
      data,
    }: {
      entityId: string;
      data: SetCustomFieldValuesPayload;
    }) => customFieldsApi.setValues(entityId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.customFields.all });
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
      qc.invalidateQueries({ queryKey: crmKeys.deals.all });
    },
  });
}

// ============================================================
//  Forecast
// ============================================================

export function useForecast(pipelineId?: string, period?: ForecastPeriod) {
  return useQuery({
    queryKey: crmKeys.deals.forecast(pipelineId, period),
    queryFn: () => forecastApi.get(pipelineId, period),
  });
}

// ============================================================
//  Import
// ============================================================

export function useImportPreview() {
  return useMutation({
    mutationFn: ({ file, entityType }: { file: File; entityType: ImportEntityType }) =>
      importApi.preview(file, entityType),
  });
}

export function useImportExecute() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: ImportExecuteRequest) => importApi.execute(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contacts.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
      qc.invalidateQueries({ queryKey: crmKeys.deals.all });
    },
  });
}

// ============================================================
//  Enrichment
// ============================================================

export function useEnrichCompany() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (companyId: string) => enrichmentApi.enrich(companyId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.companies.all });
    },
  });
}

export function useEnrichmentConfig() {
  return useQuery({
    queryKey: crmKeys.enrichment.config(),
    queryFn: () => enrichmentApi.getConfig(),
  });
}

export function useSetEnrichmentConfig() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (apiKey: string) => enrichmentApi.setConfig(apiKey),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.enrichment.config() });
    },
  });
}

// ============================================================
//  Contracts
// ============================================================

export function useContracts(companyId: string, params?: ContractsQueryParams) {
  return useQuery({
    queryKey: crmKeys.contracts.list(companyId, params),
    queryFn: () => contractsApi.list(companyId, params),
    enabled: !!companyId,
  });
}

export function useCreateContract(companyId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateContractPayload) => contractsApi.create(companyId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contracts.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.detail(companyId) });
    },
  });
}

export function useUpdateContract(companyId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ contractId, data }: { contractId: string; data: UpdateContractPayload }) =>
      contractsApi.update(companyId, contractId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contracts.all });
    },
  });
}

export function useDeleteContract(companyId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (contractId: string) => contractsApi.delete(companyId, contractId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: crmKeys.contracts.all });
      qc.invalidateQueries({ queryKey: crmKeys.companies.detail(companyId) });
    },
  });
}

// ============================================================
//  Contract Files
// ============================================================

export function useContractFiles(companyId: string, contractId: string) {
  return useQuery({
    queryKey: crmKeys.contractFiles.list(companyId, contractId),
    queryFn: () => contractFilesApi.list(companyId, contractId),
    enabled: !!companyId && !!contractId,
  });
}

export function useUploadContractFile(companyId: string, contractId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (file: File) => contractFilesApi.upload(companyId, contractId, file),
    onSuccess: () => {
      qc.invalidateQueries({
        queryKey: crmKeys.contractFiles.list(companyId, contractId),
      });
    },
  });
}

export function useDeleteContractFile(companyId: string, contractId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (fileId: string) =>
      contractFilesApi.delete(companyId, contractId, fileId),
    onSuccess: () => {
      qc.invalidateQueries({
        queryKey: crmKeys.contractFiles.list(companyId, contractId),
      });
    },
  });
}

// ============================================================
//  Microsoft 365 Integrations (Phase 3)
// ============================================================

export function useIntegrations() {
  return useQuery({
    queryKey: ['integrations'],
    queryFn: () => integrationsApi.list(),
    staleTime: 60 * 1000,
  });
}

export function useDisconnectM365() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () => integrationsApi.disconnectM365(),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['integrations'] });
    },
  });
}

export function useContactEmails(contactId: string) {
  const { data: integrationsData } = useIntegrations();
  const isConnected = integrationsData?.data?.some(
    (i) => i.provider === 'MICROSOFT_365' && i.connected,
  ) ?? false;

  return useQuery({
    queryKey: ['graph', 'emails', contactId],
    queryFn: () => graphApi.getContactEmails(contactId),
    enabled: !!contactId && isConnected,
    staleTime: 5 * 60 * 1000,
  });
}

export function useContactCalendar(contactId: string) {
  const { data: integrationsData } = useIntegrations();
  const isConnected = integrationsData?.data?.some(
    (i) => i.provider === 'MICROSOFT_365' && i.connected,
  ) ?? false;

  return useQuery({
    queryKey: ['graph', 'calendar', contactId],
    queryFn: () => graphApi.getContactCalendar(contactId),
    enabled: !!contactId && isConnected,
    staleTime: 5 * 60 * 1000,
  });
}

export function useContactTasks(contactId: string) {
  const { data: integrationsData } = useIntegrations();
  const isConnected = integrationsData?.data?.some(
    (i) => i.provider === 'MICROSOFT_365' && i.connected,
  ) ?? false;

  return useQuery({
    queryKey: ['graph', 'tasks', contactId],
    queryFn: () => graphApi.getContactTasks(contactId),
    enabled: !!contactId && isConnected,
    staleTime: 5 * 60 * 1000,
  });
}

// ── Office365 Übersicht ───────────────────────────────────────────────────────

export function useOffice365Emails() {
  const { data: integrationsData } = useIntegrations();
  const isConnected = integrationsData?.data?.some(
    (i) => i.provider === 'MICROSOFT_365' && i.connected,
  ) ?? false;

  return useQuery({
    queryKey: ['office365', 'emails'],
    queryFn: () => office365Api.getEmails(),
    enabled: isConnected,
    staleTime: 5 * 60 * 1000,
  });
}

export function useOffice365Calendar() {
  const { data: integrationsData } = useIntegrations();
  const isConnected = integrationsData?.data?.some(
    (i) => i.provider === 'MICROSOFT_365' && i.connected,
  ) ?? false;

  return useQuery({
    queryKey: ['office365', 'calendar'],
    queryFn: () => office365Api.getCalendar(),
    enabled: isConnected,
    staleTime: 5 * 60 * 1000,
  });
}

export function useOffice365Contacts() {
  const { data: integrationsData } = useIntegrations();
  const isConnected = integrationsData?.data?.some(
    (i) => i.provider === 'MICROSOFT_365' && i.connected,
  ) ?? false;

  return useQuery({
    queryKey: ['office365', 'contacts'],
    queryFn: () => office365Api.getContacts(),
    enabled: isConnected,
    staleTime: 5 * 60 * 1000,
  });
}

export function useOffice365Tasks() {
  const { data: integrationsData } = useIntegrations();
  const isConnected = integrationsData?.data?.some(
    (i) => i.provider === 'MICROSOFT_365' && i.connected,
  ) ?? false;

  return useQuery({
    queryKey: ['office365', 'tasks'],
    queryFn: () => office365Api.getTasks(),
    enabled: isConnected,
    staleTime: 5 * 60 * 1000,
  });
}

export function useOffice365CalendarRange(startDate: string, endDate: string) {
  const { data: integrationsData } = useIntegrations();
  const isConnected = integrationsData?.data?.some(
    (i) => i.provider === 'MICROSOFT_365' && i.connected,
  ) ?? false;

  return useQuery({
    queryKey: ['office365', 'calendar-range', startDate, endDate],
    queryFn: () => office365Api.getCalendarRange(startDate, endDate),
    enabled: isConnected && !!startDate && !!endDate,
    staleTime: 5 * 60 * 1000,
  });
}

export function useOffice365MailFolders() {
  const { data: integrationsData } = useIntegrations();
  const isConnected = integrationsData?.data?.some(
    (i) => i.provider === 'MICROSOFT_365' && i.connected,
  ) ?? false;

  return useQuery({
    queryKey: ['office365', 'folders'],
    queryFn: () => office365Api.getMailFolders(),
    enabled: isConnected,
    staleTime: 10 * 60 * 1000,
  });
}

export function useOffice365MailsInFolder(
  folderId: string | null,
  days: number,
) {
  const { data: integrationsData } = useIntegrations();
  const isConnected = integrationsData?.data?.some(
    (i) => i.provider === 'MICROSOFT_365' && i.connected,
  ) ?? false;

  return useQuery({
    queryKey: ['office365', 'folder-mails', folderId, days],
    queryFn: () => office365Api.getMailsInFolder(folderId!, days),
    enabled: isConnected && !!folderId,
    staleTime: 2 * 60 * 1000,
  });
}

export function useOffice365TasksFlat() {
  const { data: integrationsData } = useIntegrations();
  const isConnected =
    integrationsData?.data?.some(
      (i) => i.provider === 'MICROSOFT_365' && i.connected,
    ) ?? false;

  return useQuery({
    queryKey: ['office365', 'tasks-flat'],
    queryFn: () => office365Api.getTasksFlat(),
    enabled: isConnected,
    staleTime: 2 * 60 * 1000,
  });
}

export function useCrmOpenTasks() {
  return useQuery({
    queryKey: ['crm', 'activities', 'open-tasks'],
    queryFn: () => activitiesApi.getOpenTasks(),
    staleTime: 2 * 60 * 1000,
  });
}

export function usePushTaskToO365() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      title,
      bodyContent,
      dueDateISO,
    }: {
      title: string;
      bodyContent?: string;
      dueDateISO?: string;
    }) => office365Api.createTask(title, bodyContent, dueDateISO),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ['office365', 'tasks-flat'] });
    },
  });
}

export function useCompleteO365Task() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ listId, taskId }: { listId: string; taskId: string }) =>
      office365Api.completeTask(listId, taskId),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ['office365', 'tasks-flat'] });
    },
  });
}

export function useCompleteCrmTask() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) =>
      activitiesApi.update(id, { completedAt: new Date().toISOString() }),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ['crm', 'activities', 'open-tasks'] });
    },
  });
}

export function useContactByEmail(email: string | null) {
  return useQuery({
    queryKey: ['crm', 'contacts', 'lookup', email],
    queryFn: () => contactsApi.lookupByEmail(email!),
    enabled: !!email,
    staleTime: 10 * 60 * 1000,
    retry: false,
  });
}
