"use client";

import React, { useEffect, useMemo, useRef, useState } from "react";
import {
  Box,
  Typography,
  Chip,
  IconButton,
  Tooltip,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
  Button,
  Link,
} from "@mui/material";
import {
  FormatListBulleted,
  LocationOn as LocationOnIcon,
  Map as MapIcon,
} from "@mui/icons-material";
import dayjs from "dayjs";
import { useMap } from "@components/olmap/core/MapComponent";
import { queryFeaturesByIds } from "@/utils/mapQueryService";
import { GeoJSON } from "ol/format";
import Feature from "ol/Feature";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { Stroke, Style, Circle, Fill } from "ol/style";
import { bbox, featureCollection } from "@turf/turf";
import { BurstCandidate, BurstLocationResult } from "./types";
import { FLOW_DISPLAY_UNIT, toM3h } from "@utils/units";
import PanelEmptyState from "@components/olmap/common/PanelEmptyState";

interface Props {
  result: BurstLocationResult | null;
}

interface MetricCardProps {
  label: string;
  value: string;
  hint?: string;
  tone: "blue" | "orange" | "purple" | "green";
}

const toneStyles: Record<
  MetricCardProps["tone"],
  { bg: string; border: string; text: string; darkText: string }
> = {
  blue: {
    bg: "from-blue-50 to-blue-100",
    border: "border-blue-200",
    text: "text-blue-700",
    darkText: "text-blue-900",
  },
  orange: {
    bg: "from-orange-50 to-orange-100",
    border: "border-orange-200",
    text: "text-orange-700",
    darkText: "text-orange-900",
  },
  purple: {
    bg: "from-purple-50 to-purple-100",
    border: "border-purple-200",
    text: "text-purple-700",
    darkText: "text-purple-900",
  },
  green: {
    bg: "from-green-50 to-green-100",
    border: "border-green-200",
    text: "text-green-700",
    darkText: "text-green-900",
  },
};

const formatDateTime = (value?: string) =>
  value ? dayjs(value).format("MM-DD HH:mm") : "-";

const formatDateTimeRange = (start?: string, end?: string) => {
  if (!start || !end) return "-";
  return `${formatDateTime(start)} 至 ${formatDateTime(end)}`;
};

const getDataSourceLabel = (result: BurstLocationResult) =>
  result.data_source === "simulation" ? "模拟方案" : "监测数据";

const getNormalDataDescription = (result: BurstLocationResult) => {
  switch (result.observed_source) {
    case "simulation_scheme_burst_realtime_normal_timerange":
      return "正常数据读取实时模拟结果，与爆管数据使用同一时间窗。";
    case "scada_burst_scada_normal_timerange":
      return "正常数据读取监测数据；未单独指定正常时间窗时，默认使用爆管时段前一天同一时段。";
    case "scada_burst_payload_normal_timerange":
      return "爆管数据读取监测数据，正常数据来自请求载荷。";
    case "simulation_scheme_timerange":
      return "历史方案记录：爆管数据和正常数据均读取方案模拟结果。";
    case "scada_timerange":
      return "历史方案记录：爆管数据和正常数据使用同一监测时间窗。";
    case "request_payload":
      return "爆管数据和正常数据均来自请求载荷。";
    default:
      return "正常数据按后端返回的数据源规则选择。";
  }
};

const MetricCard = ({ label, value, hint, tone }: MetricCardProps) => {
  const style = toneStyles[tone];
  return (
    <Box
      className={`rounded-lg border bg-gradient-to-br p-3 shadow-sm ${style.bg} ${style.border}`}
    >
      <Typography
        variant="caption"
        className={`mb-1 block text-xs font-semibold uppercase tracking-wide ${style.text}`}
      >
        {label}
      </Typography>
      <Typography variant="body2" className={`font-bold ${style.darkText}`}>
        {value}
      </Typography>
      {hint ? (
        <Typography variant="caption" className={`mt-0.5 block text-xs opacity-80 ${style.text}`}>
          {hint}
        </Typography>
      ) : null}
    </Box>
  );
};

const EmptyState = () => (
  <PanelEmptyState
    icon={<MapIcon />}
    title="尚未生成定位结果"
    description="请在“定位参数”中运行分析，或在“方案查询”中打开历史结果。"
  />
);

const LocationResults: React.FC<Props> = ({ result }) => {
  const map = useMap();
  const highlightLayerRef = useRef<VectorLayer<VectorSource> | null>(null);
  const [highlightFeatures, setHighlightFeatures] = useState<Feature[]>([]);

  const candidatePipes = useMemo<BurstCandidate[]>(() => {
    if (!result) return [];
    const base = result.top_candidates ?? [];
    const hasLocated = base.some((item) => item.pipe_id === result.located_pipe);
    if (result.located_pipe && !hasLocated) {
      return [{ pipe_id: result.located_pipe, similarity: 1 }, ...base];
    }
    return base;
  }, [result]);

  const allCandidatePipeIds = (() => {
    const ids = candidatePipes.map((item) => item.pipe_id);
    if (result?.located_pipe) {
      ids.unshift(result.located_pipe);
    }
    return Array.from(new Set(ids.filter(Boolean)));
  })();

  useEffect(() => {
    if (!map) return;

    const layer = new VectorLayer({
      source: new VectorSource(),
      style: new Style({
        stroke: new Stroke({
          color: "#ef4444",
          width: 6,
        }),
        image: new Circle({
          radius: 8,
          fill: new Fill({ color: "#ef4444" }),
          stroke: new Stroke({ color: "#fff", width: 2 }),
        }),
        zIndex: 999,
      }),
      properties: {
        name: "爆管定位高亮",
        value: "burst_location_highlight",
        queryable: false,
      },
    });
    map.addLayer(layer);
    highlightLayerRef.current = layer;

    return () => {
      highlightLayerRef.current = null;
      map.removeLayer(layer);
    };
  }, [map]);

  useEffect(() => {
    const source = highlightLayerRef.current?.getSource();
    if (!source) return;
    source.clear();
    highlightFeatures.forEach((feature) => source.addFeature(feature));
  }, [highlightFeatures]);

  const locatePipes = async (pipeIds: string[]) => {
    if (!pipeIds.length || !map) return;

    try {
      let features = await queryFeaturesByIds(pipeIds, "geo_pipes_mat");
      if (features.length === 0) {
        features = await queryFeaturesByIds(pipeIds, "geo_pipes");
      }
      if (features.length === 0) return;

      setHighlightFeatures(features);

      const geojsonFormat = new GeoJSON();
      const geojsonFeatures = features.map((feature) => geojsonFormat.writeFeatureObject(feature));
      // @ts-ignore turf typing with ol geojson objects
      const extent = bbox(featureCollection(geojsonFeatures));
      map.getView().fit(extent, {
        maxZoom: 19,
        duration: 1000,
        padding: [100, 100, 100, 100],
      });
    } catch (error) {
      console.error("Locate failed", error);
    }
  };

  if (!result) {
    return <EmptyState />;
  }

  const burstSamples = result.pressure_samples?.burst ?? 0;
  const normalSamples = result.pressure_samples?.normal ?? 0;
  const elapsedText =
    result.elapsed_seconds && result.elapsed_seconds > 0
      ? `${result.elapsed_seconds.toFixed(1)} s`
      : "-";
  const bestSimilarity = candidatePipes[0]?.similarity ?? 0;
  const burstTime = result.scada_window?.burst_start
    ? formatDateTime(result.scada_window.burst_start)
    : "-";
  const burstWindow = formatDateTimeRange(
    result.scada_window?.burst_start,
    result.scada_window?.burst_end,
  );
  const normalWindow = formatDateTimeRange(
    result.scada_window?.normal_start,
    result.scada_window?.normal_end,
  );
  const sourceLabel = getDataSourceLabel(result);
  const normalDataDescription = getNormalDataDescription(result);
  const simulationBurstIds = result.simulation_scheme?.burst_ids ?? [];

  return (
    <Box className="h-full overflow-auto p-1">
      {/* Header & Metrics */}
      <Box className="mb-4 space-y-3">
        <Box className="flex items-center justify-between px-1">
          <Box className="flex items-center gap-2">
            <Box className="h-4 w-1 rounded-full bg-blue-600" />
            <Typography
              variant="h6"
              className="truncate font-bold text-gray-900"
              sx={{ fontSize: "1.1rem" }}
              title={result.scheme_name}
            >
              {result.scheme_name || "爆管定位结果"}
            </Typography>
          </Box>
          <Box className="flex items-center gap-2">
            {result.username ? (
              <Chip
                label={result.username}
                size="small"
                sx={{
                  height: 24,
                  backgroundColor: "#f3f4f6",
                  color: "#4b5563",
                  border: "none",
                  fontWeight: 500,
                }}
              />
            ) : null}
            <Button
              size="small"
              variant="outlined"
              startIcon={<LocationOnIcon />}
              onClick={() => locatePipes([result.located_pipe])}
              disabled={!result.located_pipe}
              sx={{
                height: 24,
                minWidth: 0,
                padding: "0 8px",
                borderColor: "#bfdbfe",
                color: "#2563eb",
                fontSize: "0.75rem",
                "&:hover": { borderColor: "#60a5fa", backgroundColor: "#eff6ff" },
              }}
            >
              定位
            </Button>
          </Box>
        </Box>

        <Box className="grid grid-cols-2 gap-3">
          <MetricCard
            label="定位管段"
            value={result.located_pipe || "-"}
            tone="blue"
          />
          <MetricCard
            label="估计漏损量"
            value={`${toM3h(result.burst_leakage, "m³/s").toFixed(2)} ${FLOW_DISPLAY_UNIT}`}
            tone="orange"
          />
          <MetricCard
            label="最佳相似度"
            value={`${(bestSimilarity * 100).toFixed(1)}%`}
            tone="purple"
          />
          <MetricCard
            label="爆管时间"
            value={burstTime}
            tone="green"
          />
        </Box>

        <Box className="rounded-lg border border-gray-200 bg-gray-50 px-3 py-2">
          <Box className="mb-1 flex flex-wrap items-center gap-1.5">
            <Chip
              size="small"
              label={sourceLabel}
              color={result.data_source === "simulation" ? "secondary" : "primary"}
              sx={{ height: 22, fontSize: "0.72rem", fontWeight: 600 }}
            />
            <Typography variant="caption" className="text-gray-600">
              正常数据选择说明
            </Typography>
          </Box>
          <Typography variant="caption" className="block leading-5 text-gray-700">
            {normalDataDescription}
          </Typography>
          <Typography variant="caption" className="mt-1 block leading-5 text-gray-500">
            爆管窗口: {burstWindow}；正常窗口: {normalWindow}
          </Typography>
          {result.data_source === "simulation" && result.simulation_scheme?.name ? (
            <Typography variant="caption" className="mt-1 block truncate text-purple-600">
              爆管方案: {result.simulation_scheme.name}
            </Typography>
          ) : null}
          {simulationBurstIds.length > 0 ? (
            <Box className="mt-1 flex flex-wrap items-center gap-1">
              <Typography variant="caption" className="text-purple-600">
                模拟管段:
              </Typography>
              {simulationBurstIds.map((pipeId) => (
                <Link
                  key={pipeId}
                  component="button"
                  variant="caption"
                  onClick={() => locatePipes([pipeId])}
                  title={pipeId}
                  sx={{
                    maxWidth: 132,
                    color: "#7c3aed",
                    fontSize: "0.75rem",
                    fontWeight: 700,
                    lineHeight: "22px",
                    cursor: "pointer",
                    overflow: "hidden",
                    textOverflow: "ellipsis",
                    whiteSpace: "nowrap",
                    textDecoration: "underline",
                    textUnderlineOffset: "2px",
                    "&:hover": {
                      color: "#5b21b6",
                    },
                  }}
                >
                  {pipeId}
                </Link>
              ))}
              <Button
                size="small"
                variant="text"
                startIcon={<LocationOnIcon />}
                onClick={() => locatePipes(simulationBurstIds)}
                sx={{
                  minWidth: 0,
                  px: 0.5,
                  py: 0,
                  color: "#7c3aed",
                  fontSize: "0.72rem",
                }}
              >
                定位全部
              </Button>
            </Box>
          ) : null}
        </Box>
      </Box>

      {/* Candidate List */}
      <Box className="overflow-hidden rounded-xl border border-gray-100 bg-white shadow-sm">
        <Box className="flex items-center justify-between border-b border-gray-100 bg-white px-4 py-3">
          <Box className="flex items-center gap-2">
            <FormatListBulleted className="h-5 w-5 text-blue-600" />
            <Typography variant="subtitle1" className="font-bold text-gray-800">
              候选管段列表
            </Typography>
          </Box>
          <Box className="flex items-center gap-1">
            <Chip
              size="small"
              label={`${candidatePipes.length} 条`}
              sx={{
                height: 22,
                backgroundColor: "rgba(37, 99, 235, 0.08)",
                color: "#2563eb",
                fontWeight: 600,
                fontSize: "0.75rem",
                border: "none",
              }}
            />
            <Tooltip title="定位所有管段">
              <span>
                <IconButton
                  size="small"
                  onClick={() => locatePipes(allCandidatePipeIds)}
                  disabled={allCandidatePipeIds.length === 0}
                  className="text-blue-600 hover:bg-blue-50 disabled:text-gray-300"
                >
                  <LocationOnIcon fontSize="small" />
                </IconButton>
              </span>
            </Tooltip>
          </Box>
        </Box>
        <Table size="small">
          <TableHead>
            <TableRow sx={{ backgroundColor: "#f8fafc" }}>
              <TableCell sx={{ fontWeight: 600, color: "#64748b", py: 1.5, pl: 3 }}>
                排名
              </TableCell>
              <TableCell sx={{ fontWeight: 600, color: "#64748b", py: 1.5 }}>
                管段 ID
              </TableCell>
              <TableCell align="right" sx={{ fontWeight: 600, color: "#64748b", py: 1.5 }}>
                相似度
              </TableCell>
              <TableCell align="right" sx={{ fontWeight: 600, color: "#64748b", py: 1.5, pr: 3 }}>
                操作
              </TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {candidatePipes.map((candidate, index) => {
              const similarityPercent = candidate.similarity * 100;
              const isTop = index === 0;
              return (
                <TableRow
                  key={candidate.pipe_id}
                  hover
                  sx={{
                    "&:last-child td, &:last-child th": { border: 0 },
                    backgroundColor: isTop ? "#eff6ff" : "inherit",
                  }}
                  className="transition-colors"
                >
                  <TableCell sx={{ pl: 3, py: 1.2 }}>
                    <Box
                      className={`flex h-5 w-5 items-center justify-center rounded-full text-xs font-bold ${isTop ? "bg-blue-600 text-white" : "bg-gray-200 text-gray-600"
                        }`}
                    >
                      {index + 1}
                    </Box>
                  </TableCell>
                  <TableCell sx={{ py: 1.2 }}>
                    <Typography
                      variant="body2"
                      className={`font-medium ${isTop ? "text-blue-700" : "text-gray-700"}`}
                    >
                      {candidate.pipe_id}
                    </Typography>
                  </TableCell>
                  <TableCell align="right" sx={{ py: 1.2 }}>
                    <Box className="flex flex-col items-end gap-1">
                      <Typography
                        variant="body2"
                        className={`font-medium ${isTop ? "text-blue-700" : "text-gray-700"}`}
                      >
                        {similarityPercent.toFixed(2)}%
                      </Typography>
                      <Box className="h-1.5 w-24 overflow-hidden rounded-full bg-gray-100">
                        <Box
                          className={`h-full rounded-full ${isTop ? "bg-blue-500" : "bg-gray-400"}`}
                          style={{ width: `${similarityPercent}%` }}
                        />
                      </Box>
                    </Box>
                  </TableCell>
                  <TableCell align="right" sx={{ pr: 3, py: 1.2 }}>
                    <IconButton
                      size="small"
                      onClick={() => locatePipes([candidate.pipe_id])}
                      className="text-blue-600 hover:bg-blue-50"
                      title="定位"
                    >
                      <LocationOnIcon fontSize="small" />
                    </IconButton>
                  </TableCell>
                </TableRow>
              );
            })}
          </TableBody>
        </Table>
      </Box>
    </Box>
  );
};

export default LocationResults;
