"use client";

import React, { useEffect, useMemo, useRef, useState } from "react";
import { Box, Button, Chip, Tooltip, Typography } from "@mui/material";
import { DataGrid, GridColDef } from "@mui/x-data-grid";
import { zhCN } from "@mui/x-data-grid/locales";
import {
  FormatListBulleted,
  InfoOutlined as InfoOutlinedIcon,
  Room as RoomIcon,
  ShowChart as ShowChartIcon,
  CheckCircleOutline as CheckCircleIcon,
  ErrorOutline as ErrorOutlineIcon,
} from "@mui/icons-material";
import ReactECharts from "echarts-for-react";
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 { Circle, Fill, Stroke, Style } from "ol/style";
import { bbox, featureCollection } from "@turf/turf";
import { BurstDetectionResult, BurstDetectionRow } from "./types";

interface Props {
  result: BurstDetectionResult | 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 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 = () => (
  <Box className="flex h-full flex-col items-center justify-center bg-gray-50/50 p-6 text-center">
    <Box className="mb-4 rounded-full bg-white p-6 shadow-sm">
      <ShowChartIcon sx={{ fontSize: 48, color: "#cbd5e1" }} />
    </Box>
    <Typography variant="h6" className="mb-1 font-bold text-gray-700">
      等待侦测结果
    </Typography>
    <Typography variant="body2" className="max-w-xs text-gray-500">
      提交一次爆管侦测后，这里会展示异常天数、分数趋势、最新测点排名和结果表格。
    </Typography>
  </Box>
);

const getScoreLevel = (score: number) => {
  if (score <= -0.6) return { label: "高风险", color: "error" as const };
  if (score <= -0.2) return { label: "需关注", color: "warning" as const };
  return { label: "正常", color: "success" as const };
};

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

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

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

    const layer = new VectorLayer({
      source: new VectorSource(),
      style: new Style({
        stroke: new Stroke({ color: "#ef4444", width: 4 }),
        image: new Circle({
          radius: 7,
          fill: new Fill({ color: "#ef4444" }),
          stroke: new Stroke({ color: "#fff", width: 2 }),
        }),
        zIndex: 999,
      }),
      properties: {
        name: "爆管侦测高亮",
        value: "burst_detection_highlight",
      },
    });

    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 defaultSelectedDay = useMemo(
    () =>
      result?.summary?.most_anomalous_day ??
      result?.summary?.latest_day?.Day ??
      result?.rows[0]?.Day ??
      null,
    [result],
  );

  const activeSelectedDay = selectedDay ?? defaultSelectedDay;

  const selectedRow = useMemo<BurstDetectionRow | null>(() => {
    if (!result || activeSelectedDay === null) return null;
    return result.rows.find((row) => row.Day === activeSelectedDay) ?? null;
  }, [activeSelectedDay, result]);

  const scoreSeries = useMemo(
    () =>
      result?.rows.map((row) => ({
        value: [row.Day, Number(row.Score.toFixed(4))],
        itemStyle: {
          color: row.IsBurst ? "#ef4444" : row.Score <= -0.2 ? "#f59e0b" : "#10b981",
        },
      })) ?? [],
    [result],
  );

  const rankingSeries = useMemo(
    () =>
      [...(result?.summary?.latest_sensor_rankings ?? [])]
        .sort((a, b) => a.latest_high_frequency_value - b.latest_high_frequency_value)
        .map((item) => ({
          name: item.sensor_node,
          value: Number(item.latest_high_frequency_value.toFixed(4)),
        })),
    [result],
  );

  const locateSensors = async (sensorIds: string[]) => {
    if (!map || sensorIds.length === 0) return;

    let features = await queryFeaturesByIds(sensorIds, "geo_junctions_mat");
    if (features.length === 0) {
      features = await queryFeaturesByIds(sensorIds, "geo_junctions");
    }
    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: 18,
      duration: 1000,
      padding: [100, 100, 100, 100],
    });
  };

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

  const latestDay = result.summary?.latest_day;
  const latestLevel = latestDay ? getScoreLevel(latestDay.Score) : getScoreLevel(0);
  const mostAnomalousRow = result.rows.find((row) => row.Day === result.summary?.most_anomalous_day) ?? null;
  const mostAnomalousLevel = getScoreLevel(mostAnomalousRow?.Score ?? 0);
  const isBurstDetected = result.summary.burst_detected;

  const chartOption = {
    tooltip: {
      trigger: "axis",
      formatter: (params: Array<{ data: { value: [number, number] } }>) => {
        const point = params[0]?.data?.value;
        if (!point) return "-";
        return `侦测日第 ${point[0]} 天<br/>异常分数：${point[1]}`;
      },
    },
    grid: { top: 30, left: 40, right: 20, bottom: 35 },
    xAxis: {
      type: "category",
      name: "侦测日",
      data: result.rows.map((row) => row.Day),
      axisLabel: { fontSize: 10 },
    },
    yAxis: {
      type: "value",
      name: "异常分数",
      axisLabel: { fontSize: 10 },
    },
    series: [
      {
        type: "line",
        smooth: true,
        symbolSize: 8,
        data: scoreSeries,
        lineStyle: { color: "#2563eb", width: 2 },
        markLine: {
          symbol: "none",
          lineStyle: { type: "dashed", color: "#94a3b8" },
          data: [{ yAxis: 0 }],
        },
      },
    ],
  };

  const rankingOption = {
    tooltip: {
      trigger: "axis",
      axisPointer: { type: "shadow" },
    },
    grid: { top: 20, left: 70, right: 20, bottom: 20 },
    xAxis: { type: "value", axisLabel: { fontSize: 10 } },
    yAxis: {
      type: "category",
      data: rankingSeries.map((item) => item.name),
      axisLabel: { fontSize: 10 },
    },
    series: [
      {
        type: "bar",
        data: rankingSeries.map((item) => ({
          value: item.value,
          itemStyle: {
            color: item.value <= -0.6 ? "#ef4444" : item.value <= -0.2 ? "#f59e0b" : "#10b981",
          },
        })),
        barWidth: 14,
      },
    ],
  };

  const columns: GridColDef[] = [
    {
      field: "Day",
      headerName: "侦测日",
      width: 96,
      valueFormatter: (value?: number) => (typeof value === "number" ? `第 ${value} 天` : "-"),
    },
    {
      field: "Score",
      headerName: "异常分数",
      width: 120,
      valueFormatter: (value?: number) => (typeof value === "number" ? value.toFixed(4) : "-"),
    },
    {
      field: "IsBurst",
      headerName: "判定结果",
      width: 120,
      renderCell: ({ value }) => {
        const level = value ? { label: "爆管异常", color: "error" as const } : { label: "正常", color: "success" as const };
        return <Chip size="small" label={level.label} color={level.color} variant="outlined" />;
      },
    },
  ];

  const rows = result.rows.map((row) => ({ id: row.Day, ...row }));

  return (
    <Box className="h-full overflow-auto p-1">
      <Box className="mb-4 space-y-3">
        {/* Status Banner */}
        <Box
          className={`rounded-lg px-4 py-3 flex items-center gap-3 border ${isBurstDetected
            ? "bg-red-50 border-red-100 text-red-900"
            : "bg-green-50 border-green-100 text-green-900"
            }`}
        >
          {isBurstDetected ? (
            <ErrorOutlineIcon className="text-red-600" />
          ) : (
            <CheckCircleIcon className="text-green-600" />
          )}
          <Box className="flex-1">
            <Typography variant="subtitle2" className="font-bold">
              {isBurstDetected
                ? `侦测到异常信号 (共 ${result.summary.anomaly_day_count} 天)`
                : "未侦测到爆管异常"}
            </Typography>
            <Typography variant="caption" className="opacity-80">
              {isBurstDetected
                ? "建议检查异常日期的压力波动情况"
                : "当前时间窗口内数据特征平稳，符合历史模式"}
            </Typography>
          </Box>
        </Box>

        {/* Header */}
        <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" }}>
              {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={<RoomIcon />}
              onClick={() =>
                locateSensors(result.summary.latest_sensor_rankings.map((item) => item.sensor_node).slice(0, 5))
              }
              sx={{
                height: 24,
                minWidth: 0,
                padding: "0 8px",
                borderColor: "#bfdbfe",
                color: "#2563eb",
                fontSize: "0.75rem",
                "&:hover": { borderColor: "#60a5fa", backgroundColor: "#eff6ff" },
              }}
            >
              定位
            </Button>
          </Box>
        </Box>

        {/* Configuration Summary */}
        <Box className="flex flex-wrap items-center gap-x-4 gap-y-2 rounded-lg border border-gray-100 bg-gray-50/50 px-3 py-2 text-xs text-gray-600">
          <Box className="flex items-center gap-1.5">
            <Box className="h-1.5 w-1.5 rounded-full bg-blue-400" />
            <span className="font-medium text-gray-700">时间窗口：</span>
            <span className="font-mono text-gray-600">
              {formatDateTime(result.scada_window?.start)} ~ {formatDateTime(result.scada_window?.end)}
            </span>
          </Box>
          <Box className="flex items-center gap-1.5">
            <Box className="h-1.5 w-1.5 rounded-full bg-purple-400" />
            <span className="font-medium text-gray-700">数据来源：</span>
            <span className="text-gray-600">
              {(() => {
                const ds = result.data_source;
                const os = result.observed_source;
                if (ds === "simulation") return "模拟数据";
                if (ds === "monitoring") return "监测数据";
                if (os === "simulation_scheme_timerange") return "模拟数据";
                if (os === "backend_timerange") return "监测数据";
                return os || "-";
              })()}
            </span>
          </Box>
        </Box>

        {/* Metrics Grid */}
        <Box className="grid grid-cols-2 gap-3">
          <MetricCard
            label="异常天数"
            value={`${result.summary.anomaly_day_count} / ${result.day_count}`}
            hint={`异常日：${result.summary.anomaly_days.join(", ") || "无"}`}
            tone={result.summary.anomaly_day_count > 0 ? "orange" : "green"}
          />
          <MetricCard
            label="最异常日"
            value={
              result.summary.burst_detected && result.summary.most_anomalous_day
                ? `第 ${result.summary.most_anomalous_day} 天`
                : "无"
            }
            hint={
              result.summary.burst_detected && mostAnomalousRow
                ? `分数 ${mostAnomalousRow.Score.toFixed(4)} · ${mostAnomalousLevel.label}`
                : "-"
            }
            tone="purple"
          />
          <MetricCard
            label="最新状态"
            value={latestLevel.label}
            hint={latestDay ? `第 ${latestDay.Day} 天 · 分数 ${latestDay.Score.toFixed(4)}` : "-"}
            tone={latestLevel.color === "success" ? "green" : "orange"}
          />
          <MetricCard
            label="测点 / 样本"
            value={`${result.sensor_nodes.length} / ${result.sample_count}`}
            hint={`每日采样点数：${result.points_per_day}`}
            tone="blue"
          />
        </Box>
      </Box>

      {/* Score Trend Chart */}
      <Box className="mb-4 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">
            <ShowChartIcon className="h-5 w-5 text-blue-600" />
            <Typography variant="subtitle1" className="font-bold text-gray-800">
              异常分数趋势
            </Typography>
          </Box>
          <Tooltip title="分数越小越异常，0 以下通常意味着更值得关注。">
            <InfoOutlinedIcon fontSize="small" className="text-gray-400" />
          </Tooltip>
        </Box>
        <Box sx={{ height: 250, px: 1.5, py: 1 }}>
          <ReactECharts
            option={chartOption}
            style={{ height: "100%", width: "100%" }}
            onEvents={{
              click: (params: { data?: { value?: [number, number] } }) => {
                const day = params?.data?.value?.[0];
                if (typeof day === "number") {
                  setSelectedDay(day);
                }
              },
            }}
          />
        </Box>
      </Box>

      {/* Selected Day Interpretation */}
      {/* <Box className="mb-4 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">
          <Typography variant="subtitle1" className="font-bold text-gray-800">
            选中日解读
          </Typography>
          {selectedRow ? (
            <Chip
              size="small"
              label={`第 ${selectedRow.Day} 天`}
              sx={{
                height: 22,
                backgroundColor: "rgba(37, 99, 235, 0.08)",
                color: "#2563eb",
                fontWeight: 600,
                fontSize: "0.75rem",
                border: "none",
              }}
            />
          ) : null}
        </Box>
        {selectedRow ? (
          <Box className="space-y-3 px-4 py-3">
            <Box className="flex items-center gap-2">
              <Chip
                label={getScoreLevel(selectedRow.Score).label}
                color={getScoreLevel(selectedRow.Score).color}
                variant="filled"
              />
            </Box>
            <Typography variant="body2" className="text-gray-700">
              异常分数：<span className="font-semibold">{selectedRow.Score.toFixed(4)}</span>
            </Typography>
            <Typography variant="body2" className="text-gray-700">
              模型判定：{selectedRow.IsBurst ? "异常日（Prediction = -1）" : "正常日（Prediction = 1）"}
            </Typography>
            <Typography variant="body2" className="text-gray-700">
              解读建议：
              {selectedRow.Score <= -0.6
                ? "高风险异常，建议优先复核对应测点的原始压力曲线与现场工况。"
                : selectedRow.Score <= -0.2
                  ? "存在可疑波动，建议结合相邻测点和调度记录进一步确认。"
                  : "未见明显异常，可作为基线日参考。"}
            </Typography>
          </Box>
        ) : (
          <Typography variant="body2" className="px-4 py-3 text-gray-500">
            请在趋势图或表格中选择一天查看详细解释。
          </Typography>
        )}
      </Box> */}

      {/* Latest Sensor Rankings */}
      {/* <Box className="mb-4 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">
          <Typography variant="subtitle1" className="font-bold text-gray-800">
            最新测点高频特征排名
          </Typography>
          <Typography variant="caption" className="text-gray-500">
            仅展示最新一天
          </Typography>
        </Box>
        <Box sx={{ height: 260, px: 1.5, py: 1 }}>
          <ReactECharts option={rankingOption} style={{ height: "100%", width: "100%" }} />
        </Box>
        <Box className="flex flex-wrap gap-2 border-t border-gray-100 px-4 py-3">
          {result.summary.latest_sensor_rankings.slice(0, 5).map((item) => (
            <Button
              key={item.sensor_node}
              size="small"
              variant="outlined"
              onClick={() => locateSensors([item.sensor_node])}
              sx={{
                borderColor: "#bfdbfe",
                color: "#2563eb",
                "&:hover": { borderColor: "#60a5fa", backgroundColor: "#eff6ff" },
              }}
            >
              {item.sensor_node}
            </Button>
          ))}
        </Box>
      </Box> */}

      {/* Results Table */}
      <Box className="mb-4 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>
          <Chip
            size="small"
            label={`${rows.length} 条`}
            sx={{
              height: 22,
              backgroundColor: "rgba(37, 99, 235, 0.08)",
              color: "#2563eb",
              fontWeight: 600,
              fontSize: "0.75rem",
              border: "none",
            }}
          />
        </Box>
        <Box sx={{ height: 320, px: 1, py: 1 }}>
          <DataGrid
            rows={rows}
            columns={columns}
            columnBufferPx={100}
            localeText={zhCN.components.MuiDataGrid.defaultProps.localeText}
            initialState={{
              pagination: { paginationModel: { pageSize: 50, page: 0 } },
            }}
            pageSizeOptions={[50]}
            hideFooterSelectedRowCount
            sx={{
              border: "none",
              "& .MuiDataGrid-cell": { borderColor: "#f0f0f0" },
              "& .MuiDataGrid-columnHeaders": { backgroundColor: "#fafafa" },
              "& .MuiDataGrid-row:hover": { backgroundColor: "#f8fafc" },
              // Hide the rows per page selector since it's fixed to 50
              "& .MuiTablePagination-selectLabel": { display: "none" },
              "& .MuiTablePagination-input": { display: "none" },
            }}
            disableRowSelectionOnClick
            onRowClick={(params) => setSelectedDay(Number(params.row.Day))}
          />
        </Box>
      </Box>
    </Box>
  );
};

export default DetectionResults;
