"use client";

import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import {
  Alert,
  Box,
  Button,
  Chip,
  GlobalStyles,
  Paper,
  Portal,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Typography,
} from "@mui/material";
import {
  DescriptionOutlined,
  PrintOutlined,
} from "@mui/icons-material";
import { NETWORK_NAME } from "@config/config";
import {
  clearPipeDiameterCache,
  getCachedPipeDiameters,
  getPipeDiameterDisplay,
  getPipeDiameterQueryKey,
  loadPipeDiameters,
  type PipeDiameterMap,
} from "./schemePipeDiameters";
import { SchemeRecord, ValveIsolationResult } from "./types";
import { getAffectedNodeCount } from "./valveIsolationScope";
import PanelEmptyState from "@components/olmap/common/PanelEmptyState";

interface AnalysisReportProps {
  scheme: SchemeRecord | null;
  valveResult: ValveIsolationResult | null;
  disabledValves: string[];
  generatedAt: Date | null;
}

interface ReportDocumentProps extends AnalysisReportProps {
  diameters: PipeDiameterMap;
  loadingDiameters: boolean;
}

const REPORT_BLUE = "#0b4f87";
const REPORT_INK = "#172435";
const REPORT_MUTED = "#5f6f80";
const REPORT_LINE = "#d8e0e8";
export const clearAnalysisReportDiameterCache = clearPipeDiameterCache;

const formatDateTime = (value: Date | string | null | undefined) => {
  if (!value) return "未记录";
  const date = value instanceof Date ? value : new Date(value);
  if (Number.isNaN(date.getTime())) return "未记录";
  return new Intl.DateTimeFormat("zh-CN", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
    hour12: false,
  }).format(date);
};

const formatDuration = (seconds: number | undefined) => {
  if (!Number.isFinite(seconds) || seconds === undefined || seconds < 0) {
    return "未记录";
  }

  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const remainingSeconds = seconds % 60;
  return [
    hours ? `${hours} 小时` : "",
    minutes ? `${minutes} 分钟` : "",
    remainingSeconds || (!hours && !minutes) ? `${remainingSeconds} 秒` : "",
  ]
    .filter(Boolean)
    .join(" ");
};

export const matchesValveAnalysis = (
  scheme: SchemeRecord | null,
  valveResult: ValveIsolationResult | null,
) => {
  const schemePipeIds = new Set(scheme?.schemeDetail?.burst_ID ?? []);
  const accidentElements = valveResult?.accident_elements ?? [];
  return (
    valveResult !== null &&
    accidentElements.length > 0 &&
    accidentElements.every((pipeId) => schemePipeIds.has(pipeId))
  );
};

const SectionTitle = ({ children }: { children: React.ReactNode }) => (
  <Stack direction="row" alignItems="center" spacing={1.25} sx={{ mb: 1.5 }}>
    <Box sx={{ width: 24, height: 3, bgcolor: REPORT_BLUE, flexShrink: 0 }} />
    <Typography
      component="h2"
      sx={{ color: REPORT_INK, fontSize: 17, fontWeight: 700 }}
    >
      {children}
    </Typography>
  </Stack>
);

const IdList = ({
  values,
  emptyText = "无",
}: {
  values: string[] | undefined;
  emptyText?: string;
}) =>
  values?.length ? (
    <Box className="flex flex-wrap gap-1.5">
      {values.map((value) => (
        <Chip
          key={value}
          label={value}
          size="small"
          variant="outlined"
          sx={{ borderColor: REPORT_LINE, color: REPORT_INK }}
        />
      ))}
    </Box>
  ) : (
    <Typography variant="body2" sx={{ color: REPORT_MUTED }}>
      {emptyText}
    </Typography>
  );

const ReportDocument: React.FC<ReportDocumentProps> = ({
  scheme,
  valveResult,
  disabledValves,
  generatedAt,
  diameters,
  loadingDiameters,
}) => {
  if (!scheme) return null;

  const pipeIds = scheme.schemeDetail?.burst_ID ?? [];
  const burstSizes = scheme.schemeDetail?.burst_size ?? [];
  const matchedValveResult = matchesValveAnalysis(scheme, valveResult)
    ? valveResult
    : null;
  const duration = scheme.schemeDetail?.modify_total_duration;
  const valveDetailRows: Array<[string, string[] | undefined]> =
    matchedValveResult
      ? [
          ["已分析事故管段", matchedValveResult.accident_elements],
          ["必关阀门", matchedValveResult.must_close_valves],
          ["可选阀门", matchedValveResult.optional_valves],
          ["不可用阀门", disabledValves],
        ]
      : [];
  if (matchedValveResult?.isolatable) {
    valveDetailRows.push(["受影响节点", matchedValveResult.affected_nodes]);
  }

  return (
    <Box
      sx={{
        width: "100%",
        minHeight: "100%",
        bgcolor: "#fff",
        color: REPORT_INK,
        p: { xs: 2, sm: 3 },
        fontFamily:
          '-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif',
      }}
    >
      <Box
        sx={{
          borderBottom: `3px solid ${REPORT_BLUE}`,
          pb: 2,
          mb: 3,
        }}
      >
        <Typography
          component="h1"
          sx={{ color: REPORT_BLUE, fontSize: 26, fontWeight: 800 }}
        >
          爆管分析报告
        </Typography>
        <Typography sx={{ mt: 0.75, color: REPORT_MUTED, fontSize: 13 }}>
          报告编号：BA-{scheme.id}　生成时间：{formatDateTime(generatedAt)}
        </Typography>
      </Box>

      <Box sx={{ mb: 3, breakInside: "avoid" }}>
        <SectionTitle>方案概况</SectionTitle>
        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
            borderTop: `1px solid ${REPORT_LINE}`,
            borderLeft: `1px solid ${REPORT_LINE}`,
          }}
        >
          {[
            ["管网", NETWORK_NAME],
            ["方案名称", scheme.schemeName],
            ["方案创建人", scheme.username || "未记录"],
            ["方案创建时间", formatDateTime(scheme.create_time)],
            ["模拟开始时间", formatDateTime(scheme.startTime)],
            ["模拟持续时间", formatDuration(duration)],
          ].map(([label, value]) => (
            <Box
              key={label}
              sx={{
                p: 1.25,
                borderRight: `1px solid ${REPORT_LINE}`,
                borderBottom: `1px solid ${REPORT_LINE}`,
              }}
            >
              <Typography sx={{ color: REPORT_MUTED, fontSize: 12 }}>
                {label}
              </Typography>
              <Typography sx={{ mt: 0.3, fontSize: 14, fontWeight: 600 }}>
                {value}
              </Typography>
            </Box>
          ))}
        </Box>
      </Box>

      <Box sx={{ mb: 3, breakInside: "avoid" }}>
        <SectionTitle>爆管模拟参数</SectionTitle>
        <TableContainer component={Paper} variant="outlined" elevation={0}>
          <Table size="small">
            <TableHead>
              <TableRow sx={{ bgcolor: "#f3f7fa" }}>
                <TableCell>序号</TableCell>
                <TableCell>爆管管段</TableCell>
                <TableCell>管径</TableCell>
                <TableCell align="right">爆管面积</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {pipeIds.length ? (
                pipeIds.map((pipeId, index) => (
                  <TableRow key={`${pipeId}-${index}`}>
                    <TableCell>{index + 1}</TableCell>
                    <TableCell sx={{ fontWeight: 600 }}>{pipeId}</TableCell>
                    <TableCell>
                      {getPipeDiameterDisplay(
                        [pipeId],
                        diameters,
                        loadingDiameters,
                      )}
                    </TableCell>
                    <TableCell align="right">
                      {Number.isFinite(burstSizes[index])
                        ? `${burstSizes[index]} cm²`
                        : "未记录"}
                    </TableCell>
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell colSpan={4} align="center">
                    未记录爆管管段
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </TableContainer>
      </Box>

      <Box sx={{ mb: 3, breakInside: "avoid" }}>
        <SectionTitle>分析结论</SectionTitle>
        <Alert
          severity={matchedValveResult?.isolatable === false ? "warning" : "info"}
          variant="outlined"
        >
          本方案记录了 {pipeIds.length} 条爆管管段，模拟持续时间为
          {formatDuration(duration)}。
          {matchedValveResult
            ? ` 当前关阀分析判定事故管段${
                matchedValveResult.isolatable ? "可以" : "无法"
              }有效隔离。`
            : " 当前会话尚未对本方案执行匹配的关阀分析。"}
        </Alert>
      </Box>

      <Box sx={{ mb: 2 }}>
        <SectionTitle>关阀分析</SectionTitle>
        {matchedValveResult ? (
          <Stack spacing={2}>
            <Box className="grid grid-cols-3 gap-2">
              {[
                ["隔离结论", matchedValveResult.isolatable ? "可隔离" : "不可隔离"],
                ["必关阀门", `${matchedValveResult.must_close_valves?.length ?? 0} 个`],
                ["受影响节点", `${getAffectedNodeCount(matchedValveResult)} 个`],
              ].map(([label, value]) => (
                <Paper
                  key={label}
                  variant="outlined"
                  sx={{ p: 1.5, textAlign: "center", breakInside: "avoid" }}
                >
                  <Typography sx={{ color: REPORT_MUTED, fontSize: 12 }}>
                    {label}
                  </Typography>
                  <Typography sx={{ mt: 0.5, fontWeight: 700 }}>
                    {value}
                  </Typography>
                </Paper>
              ))}
            </Box>
            {valveDetailRows.map(([label, values]) => (
              <Box key={label} sx={{ breakInside: "avoid" }}>
                <Typography sx={{ mb: 0.75, fontSize: 13, fontWeight: 700 }}>
                  {label}
                </Typography>
                <IdList values={values} />
              </Box>
            ))}
            {!matchedValveResult.isolatable && (
              <Alert severity="info" variant="outlined">
                不可隔离，未生成受影响节点清单。
              </Alert>
            )}
          </Stack>
        ) : (
          <Alert severity="info" variant="outlined">
            本方案尚未执行关阀分析。可在“关阀分析”页签完成分析后重新查看报告。
          </Alert>
        )}
      </Box>
    </Box>
  );
};

const AnalysisReport: React.FC<AnalysisReportProps> = ({
  scheme,
  valveResult,
  disabledValves,
  generatedAt,
}) => {
  const pipeIds = useMemo(
    () => scheme?.schemeDetail?.burst_ID ?? [],
    [scheme],
  );
  const diameterQueryKey = getPipeDiameterQueryKey(pipeIds);
  const cachedDiameters = getCachedPipeDiameters(pipeIds);
  const [diameterState, setDiameterState] = useState<{
    queryKey: string | null;
    values: PipeDiameterMap;
  }>({ queryKey: null, values: {} });
  const [printReady, setPrintReady] = useState(false);
  const printStateRef = useRef<{ title: string } | null>(null);
  const diameters = useMemo(
    () =>
      diameterState.queryKey === diameterQueryKey
        ? diameterState.values
        : cachedDiameters ?? {},
    [cachedDiameters, diameterQueryKey, diameterState],
  );
  const loadingDiameters =
    pipeIds.length > 0 &&
    diameterState.queryKey !== diameterQueryKey &&
    !cachedDiameters;

  useEffect(() => {
    if (!pipeIds.length) {
      return;
    }
    if (getCachedPipeDiameters(pipeIds)) {
      return;
    }

    let cancelled = false;

    loadPipeDiameters(pipeIds)
      .then((nextDiameters) => {
        if (!cancelled) {
          setDiameterState({
            queryKey: diameterQueryKey,
            values: nextDiameters,
          });
        }
      })
      .catch((error) => {
        console.error("查询分析报告管径失败:", error);
        if (!cancelled) {
          setDiameterState({
            queryKey: diameterQueryKey,
            values: Object.fromEntries(
              pipeIds.map((pipeId) => [pipeId, null]),
            ),
          });
        }
      });

    return () => {
      cancelled = true;
    };
  }, [diameterQueryKey, pipeIds]);

  const restoreAfterPrint = useCallback(() => {
    if (printStateRef.current) {
      document.title = printStateRef.current.title;
      printStateRef.current = null;
      document.body.classList.remove("burst-analysis-report-printing");
    }
    setPrintReady(false);
  }, []);

  useEffect(
    () => () => {
      restoreAfterPrint();
    },
    [restoreAfterPrint],
  );

  const handlePrint = () => {
    if (!scheme || printStateRef.current) return;
    printStateRef.current = { title: document.title };
    document.title = `爆管分析报告-${scheme.schemeName}`;
    document.body.classList.add("burst-analysis-report-printing");
    setPrintReady(true);
  };

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

    window.addEventListener("afterprint", restoreAfterPrint, { once: true });
    try {
      window.print();
    } catch (error) {
      console.error("打印爆管分析报告失败:", error);
      window.setTimeout(restoreAfterPrint, 0);
    }
    return () => {
      window.removeEventListener("afterprint", restoreAfterPrint);
    };
  }, [printReady, restoreAfterPrint]);

  const reportDocument = useMemo(
    () => (
      <ReportDocument
        scheme={scheme}
        valveResult={valveResult}
        disabledValves={disabledValves}
        generatedAt={generatedAt}
        diameters={diameters}
        loadingDiameters={loadingDiameters}
      />
    ),
    [
      diameters,
      disabledValves,
      generatedAt,
      loadingDiameters,
      scheme,
      valveResult,
    ],
  );

  if (!scheme) {
    return (
      <PanelEmptyState
        icon={<DescriptionOutlined />}
        title="尚未选择分析方案"
        description="请在“方案查询”中打开一个方案，再查看分析报告。"
      />
    );
  }

  return (
    <>
      <GlobalStyles
        styles={{
          ".burst-analysis-report-print-root": { display: "none" },
          "@page": { size: "A4 portrait", margin: 0 },
          "@media print": {
            "html, body": {
              width: "210mm",
              minHeight: "297mm",
              margin: 0,
              padding: 0,
              backgroundColor: "#fff",
            },
            "body.burst-analysis-report-printing > *:not(.burst-analysis-report-print-root)":
              { display: "none !important" },
            ".burst-analysis-report-print-root": {
              display: "block !important",
              width: "210mm !important",
              minHeight: "297mm !important",
              backgroundColor: "#fff !important",
            },
            ".burst-analysis-report-print-root > div": {
              padding: "14mm 16mm !important",
            },
          },
        }}
      />
      <Box className="space-y-3">
        <Box className="flex justify-end">
          <Button
            variant="contained"
            size="small"
            startIcon={<PrintOutlined />}
            onClick={handlePrint}
          >
            打印/保存 PDF
          </Button>
        </Box>
        <Paper
          data-testid="burst-analysis-report-preview"
          variant="outlined"
          sx={{ overflow: "hidden" }}
        >
          {reportDocument}
        </Paper>
      </Box>
      {printReady && (
        <Portal>
          <Box
            className="burst-analysis-report-print-root"
            aria-hidden="true"
          >
            {reportDocument}
          </Box>
        </Portal>
      )}
    </>
  );
};

export default AnalysisReport;
