import { memo } from 'react';

import type { SchoolMetadata } from '../../types';
import { POI_GROUP_COLORS } from '../../lib/consts';
import { getPoiIconUrl } from '../../lib/map-utils';
import { ts } from '../../i18n/server';

export interface PoiPopupCardData {
  name: string;
  category: string;
  icon_category?: string;
  group: string;
  emoji: string;
  school?: SchoolMetadata;
}

function getPoiGroupColor(group: string): [number, number, number] {
  const color = POI_GROUP_COLORS[group];
  if (!color) {
    throw new Error(`Missing POI group color for '${group}'`);
  }
  return color;
}

/** Best-effort web URL from a free-text website field — GIAS stores some with
 * "http://", some without, and some as bare hostnames. */
function normalizeSchoolWebsiteUrl(raw: string): string | null {
  const trimmed = raw.trim();
  if (!trimmed) return null;
  if (/^https?:\/\//i.test(trimmed)) return trimmed;
  if (/^[\w.-]+\.[a-z]{2,}/i.test(trimmed)) return `http://${trimmed}`;
  return null;
}

function renderSchoolMetadata(school: SchoolMetadata) {
  // First line collects the headline classification (phase, type, religious
  // character) so the popup is scannable even when most fields are absent.
  const headline: string[] = [];
  if (school.phase) headline.push(school.phase);
  if (school.type) headline.push(school.type);

  const pupilsLine =
    school.pupils !== undefined && school.capacity !== undefined
      ? `${school.pupils.toLocaleString()} / ${school.capacity.toLocaleString()} pupils`
      : school.pupils !== undefined
        ? `${school.pupils.toLocaleString()} pupils`
        : school.capacity !== undefined
          ? `Capacity ${school.capacity.toLocaleString()}`
          : null;

  const websiteUrl = school.website ? normalizeSchoolWebsiteUrl(school.website) : null;

  return (
    <dl className="mt-2 grid grid-cols-[auto_1fr] gap-x-2 gap-y-0.5 text-xs text-warm-600 dark:text-warm-300">
      {headline.length > 0 && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Type</dt>
          <dd className="dark:text-warm-200">{headline.join(' · ')}</dd>
        </>
      )}
      {school.age_range && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Ages</dt>
          <dd className="dark:text-warm-200">{school.age_range}</dd>
        </>
      )}
      {school.gender && school.gender !== 'Mixed' && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Gender</dt>
          <dd className="dark:text-warm-200">{school.gender}</dd>
        </>
      )}
      {pupilsLine && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Pupils</dt>
          <dd className="dark:text-warm-200">{pupilsLine}</dd>
        </>
      )}
      {school.fsm_percent !== undefined && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Free meal</dt>
          <dd className="dark:text-warm-200">{school.fsm_percent.toFixed(1)}%</dd>
        </>
      )}
      {school.ofsted_rating && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Ofsted</dt>
          <dd className="dark:text-warm-200">{school.ofsted_rating}</dd>
        </>
      )}
      {school.sixth_form === 'Has a sixth form' && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Sixth form</dt>
          <dd className="dark:text-warm-200">Yes</dd>
        </>
      )}
      {school.religious_character &&
        school.religious_character !== 'Does not apply' &&
        school.religious_character !== 'None' && (
          <>
            <dt className="text-warm-500 dark:text-warm-400">Religion</dt>
            <dd className="dark:text-warm-200">{school.religious_character}</dd>
          </>
        )}
      {school.admissions_policy && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Admissions</dt>
          <dd className="dark:text-warm-200">{school.admissions_policy}</dd>
        </>
      )}
      {school.trust && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Trust</dt>
          <dd className="dark:text-warm-200">{school.trust}</dd>
        </>
      )}
      {(school.address || school.postcode) && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Address</dt>
          <dd className="dark:text-warm-200">
            {[school.address, school.postcode].filter(Boolean).join(', ')}
          </dd>
        </>
      )}
      {school.local_authority && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">LA</dt>
          <dd className="dark:text-warm-200">{school.local_authority}</dd>
        </>
      )}
      {school.head_name && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Head</dt>
          <dd className="dark:text-warm-200">{school.head_name}</dd>
        </>
      )}
      {websiteUrl && (
        <>
          <dt className="text-warm-500 dark:text-warm-400">Website</dt>
          <dd className="truncate">
            <a
              href={websiteUrl}
              target="_blank"
              rel="noreferrer noopener"
              className="pointer-events-auto text-teal-600 hover:underline dark:text-teal-400"
            >
              {websiteUrl.replace(/^https?:\/\//, '')}
            </a>
          </dd>
        </>
      )}
    </dl>
  );
}

export const PoiPopupCardContent = memo(function PoiPopupCardContent({
  poi,
}: {
  poi: PoiPopupCardData;
}) {
  return (
    <div className="px-3 py-2 max-w-[280px]">
      <div className="flex items-center gap-2">
        <img
          src={getPoiIconUrl(poi.category, poi.emoji, poi.icon_category, poi.name)}
          alt=""
          aria-hidden="true"
          loading="lazy"
          referrerPolicy="no-referrer"
          className="h-5 w-5 shrink-0 rounded-[4px] bg-white object-contain p-0.5"
        />
        <div className="min-w-0">
          <div className="font-semibold dark:text-warm-100">{poi.name}</div>
          <div className="flex items-center gap-1.5 text-xs text-warm-500 dark:text-warm-400">
            <span
              className="inline-block w-2 h-2 rounded-full flex-shrink-0"
              style={{
                backgroundColor: `rgb(${getPoiGroupColor(poi.group).join(',')})`,
              }}
            />
            {ts(poi.category)}
          </div>
        </div>
      </div>
      {poi.school && renderSchoolMetadata(poi.school)}
    </div>
  );
});
