import { Check, Copy, Database, X } from "lucide-react";
import type { ComponentType } from "react";
import { useEffect, useRef, useState } from "react";
import {
  MAP_FOCUS_SURFACE_CLASS_NAME,
  MAP_MAJOR_PANEL_RADIUS_CLASS_NAME,
  showMapNotice
} from "@/features/map/core";
import { cn } from "@/shared/ui/cn";
import {
  StatusBadge,
  StatusDot,
  type StatusTone
} from "@/shared/ui/status";
import type { WaterNetworkSourceId } from "../map/sources";
import type { DetailFeature } from "../types";
import {
  getFeaturePanelModel,
  type FeaturePanelBadgeTone
} from "../utils/feature-properties";
import {
  PipeFeatureIcon,
  JunctionFeatureIcon,
  PumpFeatureIcon,
  ReservoirFeatureIcon,
  ScadaFeatureIcon,
  ValveFeatureIcon,
  type SupplyFeatureIconProps
} from "./supply-feature-icons";
import { FeaturePropertyList } from "./feature-property-list";

type FeaturePopoverProps = {
  feature: DetailFeature | null;
  onClose: () => void;
};

const FEATURE_LAYER_META: Record<
  WaterNetworkSourceId,
  {
    icon: ComponentType<SupplyFeatureIconProps>;
    label: string;
    headerClassName: string;
    labelClassName: string;
    iconClassName: string;
  }
> = {
  pipes: { icon: PipeFeatureIcon, label: "管线", headerClassName: "bg-teal-50/70", labelClassName: "text-teal-800", iconClassName: "bg-teal-700 text-white ring-teal-900/10" },
  junctions: { icon: JunctionFeatureIcon, label: "节点", headerClassName: "bg-blue-50/70", labelClassName: "text-blue-800", iconClassName: "bg-sky-700 text-white ring-sky-900/10" },
  valves: { icon: ValveFeatureIcon, label: "阀门", headerClassName: "bg-violet-50/70", labelClassName: "text-violet-800", iconClassName: "bg-violet-600 text-white ring-violet-900/10" },
  reservoirs: { icon: ReservoirFeatureIcon, label: "水库", headerClassName: "bg-sky-50/70", labelClassName: "text-sky-900", iconClassName: "bg-sky-800 text-white ring-sky-900/10" },
  scada: { icon: ScadaFeatureIcon, label: "SCADA", headerClassName: "bg-slate-50/80", labelClassName: "text-slate-800", iconClassName: "bg-slate-700 text-white ring-slate-900/10" },
  pumps: { icon: PumpFeatureIcon, label: "泵", headerClassName: "bg-cyan-50/70", labelClassName: "text-cyan-800", iconClassName: "bg-cyan-800 text-white ring-cyan-900/10" },
  tanks: { icon: ReservoirFeatureIcon, label: "水箱", headerClassName: "bg-teal-50/70", labelClassName: "text-teal-800", iconClassName: "bg-teal-700 text-white ring-teal-900/10" }
};

const badgeTones = {
  active: "success",
  inactive: "neutral",
  warning: "warning",
  critical: "danger",
  info: "info"
} satisfies Record<FeaturePanelBadgeTone, StatusTone>;

export function FeaturePopover({ feature, onClose }: FeaturePopoverProps) {
  const [copiedId, setCopiedId] = useState<string | null>(null);
  const copyResetTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  useEffect(() => () => {
    if (copyResetTimeoutRef.current) {
      clearTimeout(copyResetTimeoutRef.current);
    }
  }, []);

  if (!feature) {
    return null;
  }

  const panelModel = getFeaturePanelModel(feature.layer, feature.properties, feature.id);
  const layerMeta = FEATURE_LAYER_META[feature.layer];
  const LayerIcon = layerMeta.icon;
  const copied = copiedId === panelModel.id;
  const canCopy = panelModel.id !== "暂无";

  const handleCopyId = async () => {
    try {
      if (!navigator.clipboard) {
        throw new Error("Clipboard API unavailable");
      }

      await navigator.clipboard.writeText(panelModel.id);
      setCopiedId(panelModel.id);

      if (copyResetTimeoutRef.current) {
        clearTimeout(copyResetTimeoutRef.current);
      }

      copyResetTimeoutRef.current = setTimeout(() => setCopiedId(null), 1500);
    } catch {
      showMapNotice({
        tone: "error",
        title: "无法复制编号",
        message: "请手动选择编号后复制。"
      });
    }
  };

  return (
    <aside
      className={cn(
        "pointer-events-auto absolute left-1/2 top-[92px] z-20 w-[min(380px,calc(100vw-24px))] -translate-x-1/2 overflow-hidden",
        MAP_FOCUS_SURFACE_CLASS_NAME,
        MAP_MAJOR_PANEL_RADIUS_CLASS_NAME
      )}
    >
      <header className={cn("px-4 pb-3 pt-4", layerMeta.headerClassName)}>
        <div className="grid grid-cols-[48px_minmax(0,1fr)_auto] items-start gap-3">
          <span className={cn("grid h-12 w-12 place-items-center rounded-full ring-1", layerMeta.iconClassName)} aria-hidden="true">
            <LayerIcon size={24} />
          </span>

          <div className="min-w-0">
            <div className="flex min-w-0 flex-nowrap items-center gap-1.5">
              <span className={cn("min-w-0 truncate text-xs font-semibold", layerMeta.labelClassName)}>{layerMeta.label}</span>
              {panelModel.badge ? (
                <StatusBadge
                  tone={badgeTones[panelModel.badge.tone]}
                  icon={<StatusDot tone={badgeTones[panelModel.badge.tone]} />}
                >
                  {panelModel.badge.label}
                </StatusBadge>
              ) : null}
            </div>
            <h3 className="mt-1 truncate text-base font-semibold text-slate-950">{feature.title}</h3>
            <p className="mt-0.5 truncate text-xs text-slate-600 tabular-nums">编号 {panelModel.id}</p>
          </div>

          <div className="flex items-center gap-0.5">
            {canCopy ? (
              <button type="button" aria-label={copied ? "编号已复制" : "复制编号"} title={copied ? "编号已复制" : "复制编号"} onClick={() => void handleCopyId()} className="relative grid h-10 w-10 shrink-0 place-items-center rounded-xl text-slate-500 [@media(hover:hover)]:hover:bg-white/70 [@media(hover:hover)]:hover:text-slate-950">
                <Copy size={15} aria-hidden="true" className={cn("absolute transition-[opacity,transform] duration-150", copied ? "scale-90 opacity-0" : "scale-100 opacity-100")} />
                <Check size={16} aria-hidden="true" className={cn("status-tone-success absolute text-[var(--status-foreground)] transition-[opacity,transform] duration-150", copied ? "scale-100 opacity-100" : "scale-90 opacity-0")} />
              </button>
            ) : null}
            <button type="button" aria-label="关闭要素信息" title="关闭要素信息" onClick={onClose} className="grid h-10 w-10 shrink-0 place-items-center rounded-xl text-slate-500 [@media(hover:hover)]:hover:bg-white/70 [@media(hover:hover)]:hover:text-slate-950">
              <X size={16} aria-hidden="true" />
            </button>
          </div>
        </div>
      </header>

      <div className="px-4 py-3">
        {panelModel.attributes.length > 0 ? (
          <>
            <div className="mb-2 flex items-center gap-2 text-xs font-semibold text-slate-500">
              <Database size={14} aria-hidden="true" />
              设施属性
            </div>
            <FeaturePropertyList entries={panelModel.attributes} variant="popover" />
          </>
        ) : (
          <p className="py-3 text-center text-sm text-slate-500">暂无可展示属性</p>
        )}
      </div>

      <span className="sr-only" aria-live="polite">
        {copied ? "编号已复制" : ""}
      </span>
    </aside>
  );
}
