'use client';

import { Loader2, MapPin } from 'lucide-react';
import * as React from 'react';
import {
  POI_ICONS,
  POI_LABELS,
  poiApi,
  type NearbyPoiResult,
  type PoiCategory,
} from '@/lib/poi-api';

interface Props {
  /** Centre coordinates of the asset (listing / project / KCN). */
  lat: number;
  lng: number;
  /** Search radius in metres. Default 1500m (~15 phút đi bộ). */
  radius?: number;
  /** Restrict to these categories. Default: 6 most relevant for residential. */
  categories?: PoiCategory[];
  /** N nearest POI shown per category. */
  limitPerCategory?: number;
  className?: string;
}

const DEFAULT_CATEGORIES: PoiCategory[] = [
  'SCHOOL_PRIMARY',
  'SCHOOL_SECONDARY',
  'HOSPITAL',
  'MARKET',
  'BANK',
  'METRO_STATION',
];

function formatDistance(m: number): string {
  if (m < 1000) return `${m} m`;
  return `${(m / 1000).toFixed(1)} km`;
}

/**
 * Sidebar widget that lists the nearest POI of each category around a
 * geo-tagged asset. Renders inside listing detail, project detail and KCN
 * detail pages.
 */
export function NearbyPoiSidebar({
  lat,
  lng,
  radius = 1500,
  categories = DEFAULT_CATEGORIES,
  limitPerCategory = 3,
  className,
}: Props) {
  const [data, setData] = React.useState<NearbyPoiResult | null>(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);

  React.useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setError(null);
    poiApi
      .nearby({ lat, lng, radius, categories, limitPerCategory })
      .then((res) => {
        if (cancelled) return;
        setData(res);
      })
      .catch((err: Error) => {
        if (cancelled) return;
        setError(err.message ?? 'Không tải được tiện ích');
      })
      .finally(() => {
        if (cancelled) return;
        setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [lat, lng, radius, categories, limitPerCategory]);

  if (loading) {
    return (
      <div
        className={`flex items-center gap-2 rounded-lg border border-border bg-card p-4 text-sm text-muted-foreground ${className ?? ''}`}
      >
        <Loader2 className="h-4 w-4 animate-spin" />
        Đang tải tiện ích xung quanh…
      </div>
    );
  }

  if (error) {
    return (
      <div
        className={`rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive ${className ?? ''}`}
      >
        {error}
      </div>
    );
  }

  if (!data || data.all.length === 0) {
    return (
      <div
        className={`rounded-lg border border-border bg-card p-4 text-sm text-muted-foreground ${className ?? ''}`}
      >
        Chưa có dữ liệu tiện ích trong bán kính {formatDistance(radius)}.
      </div>
    );
  }

  return (
    <div className={`rounded-lg border border-border bg-card ${className ?? ''}`}>
      <div className="flex items-center justify-between border-b border-border px-4 py-2.5">
        <h3 className="text-sm font-semibold text-foreground">Tiện ích xung quanh</h3>
        <span className="text-xs text-muted-foreground">
          {data.meta.totalCount} điểm · bán kính {formatDistance(data.meta.radiusMeters)}
        </span>
      </div>
      <div className="flex flex-col divide-y divide-border">
        {categories.map((cat) => {
          const items = data.byCategory[cat] ?? [];
          if (items.length === 0) return null;
          return (
            <div key={cat} className="px-4 py-2.5">
              <div className="mb-1.5 flex items-center gap-1.5 text-xs font-medium uppercase text-muted-foreground">
                <span aria-hidden>{POI_ICONS[cat]}</span>
                {POI_LABELS[cat]}
              </div>
              <ul className="flex flex-col gap-1.5">
                {items.map((p) => (
                  <li key={p.id} className="flex items-start gap-2 text-sm">
                    <MapPin className="mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" />
                    <div className="min-w-0 flex-1">
                      <div className="truncate font-medium text-foreground">{p.name}</div>
                      {p.address && (
                        <div className="truncate text-xs text-muted-foreground">{p.address}</div>
                      )}
                    </div>
                    <span className="shrink-0 rounded bg-muted px-1.5 py-0.5 text-xs font-medium text-muted-foreground">
                      {formatDistance(p.distanceM)}
                    </span>
                  </li>
                ))}
              </ul>
            </div>
          );
        })}
      </div>
    </div>
  );
}
