import { formatPhone } from '~/utils/formatters/phone';

export interface ConstructeurTelephoneSummary {
  numero?: string | null;
  label?: string | null;
}

export interface ConstructeurSummary {
  id: string;
  name?: string | null;
  email?: string | null;
  // Legacy single-phone string: still exposed by the machine-structure normalization.
  phone?: string | null;
  // Multi-phone list: exposed by the /constructeurs API resource.
  telephones?: ConstructeurTelephoneSummary[] | null;
}

type ConstructeurPhoneSource = {
  phone?: string | null;
  telephones?: ConstructeurTelephoneSummary[] | null;
} | null | undefined;

export const constructeurPhones = (
  constructeur: ConstructeurPhoneSource,
): Array<{ numero: string; label: string | null }> => {
  if (!constructeur) {
    return [];
  }
  const list = Array.isArray(constructeur.telephones)
    ? constructeur.telephones
      .filter((t): t is ConstructeurTelephoneSummary => Boolean(t && t.numero && String(t.numero).trim()))
      .map(t => ({ numero: String(t.numero).trim(), label: (t.label ?? null) || null }))
    : [];
  if (!list.length && constructeur.phone && constructeur.phone.trim()) {
    return [{ numero: constructeur.phone.trim(), label: null }];
  }
  return list;
};

export const constructeurPrimaryPhone = (
  constructeur: ConstructeurPhoneSource,
): string | null => {
  const phones = constructeurPhones(constructeur);
  return phones.length ? phones[0]!.numero : null;
};

export interface ConstructeurLinkEntry {
  linkId?: string;
  constructeurId: string;
  constructeur?: ConstructeurSummary | null;
  supplierReference: string | null;
}

export const constructeurIdsFromLinks = (links: ConstructeurLinkEntry[]): string[] =>
  links.map(l => l.constructeurId).filter(Boolean);

export const parseConstructeurLinksFromApi = (
  apiLinks: any[],
): ConstructeurLinkEntry[] => {
  if (!Array.isArray(apiLinks)) return [];
  return apiLinks
    .filter(link => link && typeof link === 'object')
    .map(link => ({
      linkId: link.id || (typeof link['@id'] === 'string' ? link['@id'].split('/').pop() : undefined),
      constructeurId: typeof link.constructeur === 'string'
        ? link.constructeur.split('/').pop()!
        : link.constructeur?.id || '',
      constructeur: typeof link.constructeur === 'object' ? link.constructeur : null,
      supplierReference: link.supplierReference ?? null,
    }));
};

const isObject = (value: unknown): value is Record<string, unknown> =>
  Boolean(value) && typeof value === 'object' && !Array.isArray(value);

const toStringId = (value: unknown): string | null => {
  if (typeof value !== 'string') {
    return null;
  }
  const trimmed = value.trim();
  if (!trimmed) {
    return null;
  }
  if (trimmed.includes('/')) {
    const parts = trimmed.split('/').filter(Boolean);
    return parts.length ? (parts[parts.length - 1] ?? null) : null;
  }
  return trimmed;
};

export const uniqueConstructeurIds = (...sources: unknown[]): string[] => {
  const ids = new Set<string>();

  const pushId = (value: unknown) => {
    const id = toStringId(value);
    if (id) {
      ids.add(id);
    }
  };

  const explore = (value: unknown): void => {
    if (!value) {
      return;
    }
    if (Array.isArray(value)) {
      value.forEach(explore);
      return;
    }
    if (typeof value === 'string') {
      pushId(value);
      return;
    }
    if (isObject(value)) {
      if (Array.isArray(value.constructeurIds)) {
        value.constructeurIds.forEach(pushId);
      }
      if (value.constructeurId) {
        pushId(value.constructeurId);
      }
      if (Array.isArray(value.constructeurs)) {
        value.constructeurs.forEach(explore);
      }
      if (value.constructeur) {
        explore(value.constructeur);
      }
      // Extract ID from constructeur-like objects, but skip component/piece/product entities
      if (typeof value.id === 'string' && !value.typeComposant && !value.typePiece && !value.typeProduct) {
        pushId(value.id);
      }
      return;
    }
  };

  sources.forEach(explore);
  return Array.from(ids);
};

export const resolveConstructeurs = (
  ids: string[],
  ...candidatePools: Array<ConstructeurSummary[] | null | undefined>
): ConstructeurSummary[] => {
  if (!Array.isArray(ids) || ids.length === 0) {
    return [];
  }

  const index = new Map<string, ConstructeurSummary>();
  const register = (pool?: ConstructeurSummary[] | null) => {
    if (!Array.isArray(pool)) {
      return;
    }
    pool.forEach((entry) => {
      if (entry && typeof entry === 'object' && typeof entry.id === 'string') {
        index.set(entry.id, entry);
      }
    });
  };

  candidatePools.forEach(register);

  return ids
    .map((id) => index.get(id))
    .filter((item): item is ConstructeurSummary => Boolean(item))
    .map((item) => ({ ...item }));
};

export const formatConstructeurContact = (
  constructeur?: ConstructeurSummary | null,
): string => {
  if (!constructeur) {
    return '';
  }

  const primary = constructeurPrimaryPhone(constructeur);
  const phone = formatPhone(primary) || primary || null;

  return [constructeur.email, phone].filter(Boolean).join(' • ');
};

