/**
 * Keep only main property types like Symfony CRM (Maison, Appartement, Terrain…).
 * Hide rows that are really subtypes (Duplex, Triplex, Étage…) wrongly stored as types.
 */

const CANONICAL_MAIN_SLUGS = [
  'maison',
  'villa',
  'appartement',
  'appart',
  'terrain',
  'immeuble',
  'professionnel',
  'bureau',
  'local',
  'fond-de-commerce',
  'commerce',
] as const;

export type TypeRow = { id: number; name: string; name_slug?: string | null };
export type SubTypeRow = {
  id: number;
  name: string;
  name_slug?: string | null;
  property_type_id?: number;
  propertyTypeId?: number;
};

export function subTypeParentId(row: SubTypeRow): number {
  const n = Number(row.property_type_id ?? row.propertyTypeId ?? 0);
  return Number.isFinite(n) ? n : 0;
}

function norm(s: string): string {
  return s
    .toLowerCase()
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .trim();
}

function slugOf(row: { name?: string; name_slug?: string | null }): string {
  const slug = norm(row.name_slug ?? '');
  if (slug) return slug;
  return norm(row.name ?? '');
}

function isCanonicalMain(slug: string, name: string): boolean {
  const n = norm(name);
  for (const c of CANONICAL_MAIN_SLUGS) {
    if (slug === c || slug.includes(c) || n.includes(c)) return true;
  }
  return false;
}

/**
 * Filter API property types to match Symfony web create dropdown.
 */
export function filterMainPropertyTypes<T extends TypeRow>(
  types: T[],
  subTypes: SubTypeRow[],
): T[] {
  if (!types.length) return types;

  const childCount = new Map<number, number>();
  for (const st of subTypes) {
    const pid = subTypeParentId(st);
    if (pid <= 0) continue;
    childCount.set(pid, (childCount.get(pid) ?? 0) + 1);
  }

  const subtypeKeys = new Set<string>();
  for (const st of subTypes) {
    subtypeKeys.add(slugOf(st));
    subtypeKeys.add(norm(st.name));
  }

  const filtered = types.filter((t) => {
    const slug = slugOf(t);
    const name = norm(t.name);
    const hasChildren = (childCount.get(t.id) ?? 0) > 0;

    // Duplex / Triplex / Étage stored as type but also as subtype elsewhere → hide
    const looksLikeSubtypeElsewhere =
      !hasChildren &&
      (subtypeKeys.has(slug) || subtypeKeys.has(name)) &&
      !isCanonicalMain(slug, t.name);

    if (looksLikeSubtypeElsewhere) return false;

    // Keep canonical mains (Maison, Appartement…) even without subtypes
    if (isCanonicalMain(slug, t.name)) return true;

    // Keep any other type that actually has sous-types (real parent)
    if (hasChildren) return true;

    return false;
  });

  // Prefer Symfony-like order
  const order = ['maison', 'villa', 'appartement', 'terrain', 'immeuble', 'professionnel', 'bureau', 'local'];
  return [...filtered].sort((a, b) => {
    const sa = slugOf(a);
    const sb = slugOf(b);
    const ia = order.findIndex((o) => sa.includes(o) || norm(a.name).includes(o));
    const ib = order.findIndex((o) => sb.includes(o) || norm(b.name).includes(o));
    const ra = ia === -1 ? 99 : ia;
    const rb = ib === -1 ? 99 : ib;
    if (ra !== rb) return ra - rb;
    return a.name.localeCompare(b.name, 'fr');
  });
}

export function filterSubTypesForTypes(
  subTypes: SubTypeRow[],
  mainTypes: TypeRow[],
): Array<SubTypeRow & { property_type_id: number }> {
  const ids = new Set(mainTypes.map((t) => Number(t.id)));
  return subTypes
    .map((s) => ({ ...s, property_type_id: subTypeParentId(s) }))
    .filter((s) => s.property_type_id > 0 && ids.has(s.property_type_id));
}
