import type { InventoryPropertySummary } from '@/lib/velocityPlatformClient';
import type { Unit } from '@/types';

function asRecord(value: unknown): Record<string, unknown> {
  return value && typeof value === 'object' && !Array.isArray(value)
    ? value as Record<string, unknown>
    : {};
}

function asNumber(value: unknown): number | null {
  if (typeof value === 'number' && Number.isFinite(value)) {
    return value;
  }
  if (typeof value === 'string') {
    const cleaned = value.replace(/[^0-9.]/g, '');
    const parsed = Number(cleaned);
    if (Number.isFinite(parsed) && parsed > 0) {
      return parsed;
    }
  }
  return null;
}

function pickFirstNumber(values: unknown[]): number | null {
  for (const value of values) {
    const parsed = asNumber(value);
    if (parsed !== null) {
      return parsed;
    }
  }
  return null;
}

function mapInventoryStatus(status: string): Unit['status'] {
  switch ((status ?? '').toLowerCase()) {
    case 'active':
      return 'available';
    case 'under_review':
      return 'reserved';
    case 'archived':
      return 'hold';
    default:
      return 'hold';
  }
}

function inferArea(unitMix: unknown[]): number {
  for (const item of unitMix) {
    const record = asRecord(item);
    const area = pickFirstNumber([
      record.avg_area_sqm,
      record.avg_area,
      record.area_sqm,
      record.area,
      record.size_sqm,
      record.size,
    ]);
    if (area !== null) {
      return Math.round(area);
    }
  }
  return 0;
}

function inferPrice(priceBands: unknown[]): number {
  for (const item of priceBands) {
    const record = asRecord(item);
    const price = pickFirstNumber([
      record.from,
      record.min,
      record.price,
      record.starting_price,
      record.amount,
      record.value,
    ]);
    if (price !== null) {
      return Math.round(price);
    }
  }
  return 0;
}

function inferType(propertyType: string, unitMix: unknown[]): Unit['type'] {
  const normalizedPropertyType = (propertyType ?? '').toLowerCase();
  if (normalizedPropertyType.includes('penthouse')) return 'penthouse';
  if (normalizedPropertyType.includes('studio')) return 'studio';
  if (normalizedPropertyType.includes('1')) return '1br';
  if (normalizedPropertyType.includes('2')) return '2br';
  if (normalizedPropertyType.includes('3')) return '3br';

  for (const item of unitMix) {
    const record = asRecord(item);
    const raw = String(
      record.type ?? record.unit_type ?? record.label ?? record.configuration ?? ''
    ).toLowerCase();
    if (raw.includes('penthouse')) return 'penthouse';
    if (raw.includes('studio')) return 'studio';
    if (raw.includes('1')) return '1br';
    if (raw.includes('2')) return '2br';
    if (raw.includes('3')) return '3br';
  }

  return '2br';
}

function inferFloor(unitMix: unknown[]): number {
  for (const item of unitMix) {
    const record = asRecord(item);
    const floor = pickFirstNumber([record.floor, record.level, record.start_floor]);
    if (floor !== null) {
      return Math.round(floor);
    }
  }
  return 0;
}

export function mapInventoryPropertySummaryToUnit(
  property: InventoryPropertySummary,
  index: number,
): Unit {
  const location = asRecord(property.location);
  const unitMix = Array.isArray(property.unit_mix) ? property.unit_mix : [];
  const priceBands = Array.isArray(property.price_bands) ? property.price_bands : [];
  const district = typeof location.district === 'string' ? location.district : '';
  const city = typeof location.city === 'string' ? location.city : '';
  const view = [district, city].filter(Boolean).join(', ') || property.developer_name || 'Location pending';

  return {
    id: property.property_id,
    unitNumber: property.project_name || `Property ${index + 1}`,
    type: inferType(property.property_type, unitMix),
    floor: inferFloor(unitMix),
    area: inferArea(unitMix),
    price: inferPrice(priceBands),
    status: mapInventoryStatus(property.status),
    view,
    lastUpdated: new Date(property.ingested_at ?? property.created_at ?? Date.now()),
  };
}
