/**
 * Unified Contact (Rentman-style) hooks and standalone API functions.
 */

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiGet, apiPost, apiPut, apiDelete } from './client';
import { PaginatedResponse } from './types';

export interface ContactPerson {
  id: string;
  contact_id: string;
  displayname: string;
  firstname?: string | null;
  middle_name?: string | null;
  lastname?: string | null;
  function?: string | null;
  phone?: string | null;
  mobilephone?: string | null;
  email?: string | null;
  street?: string | null;
  number?: string | null;
  postalcode?: string | null;
  city?: string | null;
  state?: string | null;
  country?: string | null;
  tags?: string | null;
  custom?: Record<string, any> | null;
  created_at?: string;
  updated_at?: string;
}

export interface UnifiedContact {
  id: string;
  type: 'company' | 'person';
  displayname: string;
  name?: string | null;
  firstname?: string | null;
  surname?: string | null;
  surfix?: string | null;
  ext_name_line?: string | null;
  gender?: string | null;
  code?: string | null;
  accounting_code?: string | null;
  vendor_accounting_code?: string | null;
  // Mailing address
  mailing_street?: string | null;
  mailing_number?: string | null;
  mailing_unit_number?: string | null;
  mailing_district?: string | null;
  mailing_extra_address_line?: string | null;
  mailing_postalcode?: string | null;
  mailing_city?: string | null;
  mailing_state?: string | null;
  mailing_country?: string | null;
  // Visit address
  visit_street?: string | null;
  visit_number?: string | null;
  visit_unit_number?: string | null;
  visit_district?: string | null;
  visit_extra_address_line?: string | null;
  visit_postalcode?: string | null;
  visit_city?: string | null;
  visit_state?: string | null;
  // Invoice address
  invoice_street?: string | null;
  invoice_number?: string | null;
  invoice_unit_number?: string | null;
  invoice_district?: string | null;
  invoice_extra_address_line?: string | null;
  invoice_postalcode?: string | null;
  invoice_city?: string | null;
  invoice_state?: string | null;
  invoice_country?: string | null;
  country?: string | null;
  // Communication
  phone_1?: string | null;
  phone_2?: string | null;
  email_1?: string | null;
  email_2?: string | null;
  website?: string | null;
  // Financial
  vat_code?: string | null;
  fiscal_code?: string | null;
  commerce_code?: string | null;
  purchase_number?: string | null;
  bic?: string | null;
  bank_account?: string | null;
  // Discounts
  discount_crew: number;
  discount_transport: number;
  discount_rental: number;
  discount_sale: number;
  discount_subrent: number;
  discount_total: number;
  // Geo
  latitude?: number | null;
  longitude?: number | null;
  // Notes
  projectnote?: string | null;
  projectnote_title?: string | null;
  contact_warning?: string | null;
  tags?: string | null;
  image?: string | null;
  custom?: Record<string, any> | null;
  folder_id?: string | null;
  default_person_id?: string | null;
  admin_contactperson_id?: string | null;
  contact_persons?: ContactPerson[];
  created_at?: string;
  updated_at?: string;
}

export function useUnifiedContacts(
  page = 1,
  pageSize = 25,
  search?: string,
  contactType?: string,
  sortBy?: string,
  sortOrder?: string,
  folderId?: string,
) {
  const params = new URLSearchParams({ page: String(page), page_size: String(pageSize) });
  if (search) params.set('search', search);
  if (contactType) params.set('type', contactType);
  if (sortBy) params.set('sort_by', sortBy);
  if (sortOrder) params.set('sort_order', sortOrder);
  if (folderId) params.set('folder_id', folderId);
  return useQuery({
    queryKey: ['unifiedContacts', page, pageSize, search, contactType, sortBy, sortOrder, folderId],
    queryFn: () =>
      apiGet<PaginatedResponse<UnifiedContact>>(`/contacts?${params.toString()}`),
  });
}

export function useUnifiedContact(id?: string) {
  return useQuery({
    queryKey: ['unifiedContacts', id],
    queryFn: () => apiGet<UnifiedContact & { contact_persons: ContactPerson[] }>(`/contacts/${id}`),
    enabled: !!id,
  });
}

export function useCreateUnifiedContact() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (data: Partial<UnifiedContact>) => apiPost('/contacts', data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts'] });
    },
  });
}

export function useUpdateUnifiedContact() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: Partial<UnifiedContact> }) =>
      apiPut(`/contacts/${id}`, data),
    onSuccess: (_data, variables) => {
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts'] });
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts', variables.id] });
    },
  });
}

export function useDeleteUnifiedContact() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({ id, hard }: { id: string; hard?: boolean }) =>
      apiDelete(`/contacts/${id}${hard ? '?hard=true' : ''}`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts'] });
    },
  });
}

export function useContactPersons(contactId?: string) {
  return useQuery({
    queryKey: ['unifiedContacts', contactId, 'persons'],
    queryFn: () => apiGet<{ items: ContactPerson[] }>(`/contacts/${contactId}/persons`),
    enabled: !!contactId,
  });
}

export function useCreateContactPerson() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({ contactId, data }: { contactId: string; data: Partial<ContactPerson> }) =>
      apiPost(`/contacts/${contactId}/persons`, data),
    onSuccess: (_data, variables) => {
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts'] });
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts', variables.contactId] });
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts', variables.contactId, 'persons'] });
    },
  });
}

export function useUpdateContactPerson() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({ contactId, personId, data }: { contactId: string; personId: string; data: Partial<ContactPerson> }) =>
      apiPut(`/contacts/${contactId}/persons/${personId}`, data),
    onSuccess: (_data, variables) => {
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts'] });
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts', variables.contactId] });
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts', variables.contactId, 'persons'] });
    },
  });
}

export function useDeleteContactPerson() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({ contactId, personId }: { contactId: string; personId: string }) =>
      apiDelete(`/contacts/${contactId}/persons/${personId}`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['unifiedContacts'] });
    },
  });
}

// Standalone API functions (for non-hook usage)
export async function fetchContacts(
  page = 1,
  pageSize = 25,
  search?: string,
  contactType?: string,
  sortBy?: string,
  sortOrder?: string,
): Promise<PaginatedResponse<UnifiedContact>> {
  const params = new URLSearchParams({ page: String(page), page_size: String(pageSize) });
  if (search) params.set('search', search);
  if (contactType) params.set('type', contactType);
  if (sortBy) params.set('sort_by', sortBy);
  if (sortOrder) params.set('sort_order', sortOrder);
  return apiGet<PaginatedResponse<UnifiedContact>>(`/contacts?${params.toString()}`);
}

export async function fetchContact(id: string): Promise<UnifiedContact & { contact_persons: ContactPerson[] }> {
  return apiGet<UnifiedContact & { contact_persons: ContactPerson[] }>(`/contacts/${id}`);
}

export async function createContact(data: Partial<UnifiedContact>): Promise<UnifiedContact> {
  return apiPost<UnifiedContact>('/contacts', data);
}

export async function updateContact(id: string, data: Partial<UnifiedContact>): Promise<UnifiedContact> {
  return apiPut<UnifiedContact>(`/contacts/${id}`, data);
}

export async function deleteContact(id: string, hard?: boolean): Promise<void> {
  await apiDelete(`/contacts/${id}${hard ? '?hard=true' : ''}`);
}

export async function fetchContactPersons(contactId: string): Promise<{ items: ContactPerson[] }> {
  return apiGet<{ items: ContactPerson[] }>(`/contacts/${contactId}/persons`);
}

export async function createContactPerson(contactId: string, data: Partial<ContactPerson>): Promise<ContactPerson> {
  return apiPost<ContactPerson>(`/contacts/${contactId}/persons`, data);
}

export async function updateContactPerson(contactId: string, personId: string, data: Partial<ContactPerson>): Promise<ContactPerson> {
  return apiPut<ContactPerson>(`/contacts/${contactId}/persons/${personId}`, data);
}

export async function deleteContactPerson(contactId: string, personId: string): Promise<void> {
  await apiDelete(`/contacts/${contactId}/persons/${personId}`);
}
