"use client";

import React, { useMemo, useState, useCallback } from "react";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import RefreshIcon from "@mui/icons-material/Refresh";
import {
  Box,
  Button,
  CircularProgress,
  Collapse,
  FormControl,
  MenuItem,
  Select,
  TextField,
  Typography,
  IconButton,
} from "@mui/material";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { zhCN as pickerZhCN } from "@mui/x-date-pickers/locales";
import { useNotification } from "@refinedev/core";
import dayjs, { Dayjs } from "dayjs";
import "dayjs/locale/zh-cn";
import { api } from "@/lib/api";
import { NETWORK_NAME, config } from "@config/config";
import { BurstDetectionResult } from "./types";

interface Props {
  onResult: (result: BurstDetectionResult) => void;
}

interface SchemeItem {
  scheme_id: number;
  scheme_name: string;
  scheme_type: string;
  create_time: string;
  scheme_start_time: string;
  scheme_detail?: {
    modify_total_duration: number;
  };
}

const AnalysisParameters: React.FC<Props> = ({ onResult }) => {
  const { open } = useNotification();
  const [schemeName, setSchemeName] = useState(`Burst_Detection_${Date.now()}`);
  const [dataSource, setDataSource] = useState<"monitoring" | "simulation">("monitoring");
  const [schemes, setSchemes] = useState<SchemeItem[]>([]);
  const [selectedSchemeId, setSelectedSchemeId] = useState<number | "">("");
  const [schemeLoading, setSchemeLoading] = useState(false);
  const [scadaStart, setScadaStart] = useState<Dayjs | null>(dayjs().subtract(3, "day"));
  const [scadaEnd, setScadaEnd] = useState<Dayjs | null>(dayjs());
  const [mu, setMu] = useState<number>(100);
  const [pointsPerDay, setPointsPerDay] = useState<number>(96);
  const [nEstimators, setNEstimators] = useState<number>(50);
  const [contaminationInput, setContaminationInput] = useState<string>("auto");
  const [advancedOpen, setAdvancedOpen] = useState(false);
  const [running, setRunning] = useState(false);
  const isSimulationMode = dataSource === "simulation";

  const applySchemeTimeRange = useCallback((scheme: SchemeItem) => {
    const start = dayjs(scheme.scheme_start_time);
    const durationSeconds = scheme.scheme_detail?.modify_total_duration ?? 3600;
    const end = start.add(durationSeconds, "second");

    setScadaStart(start);
    setScadaEnd(end);
  }, []);

  const fetchSchemes = useCallback(
    async ({ force = false, notify = false }: { force?: boolean; notify?: boolean } = {}) => {
      if (schemeLoading || (!force && schemes.length > 0)) return;

      setSchemeLoading(true);
      try {
        const response = await api.get(`${config.BACKEND_URL}/api/v1/schemes`, {
          params: { network: NETWORK_NAME },
        });
        const burstSchemes = (response.data as SchemeItem[]).filter(
          (scheme) => scheme.scheme_type === "burst_analysis",
        );

        setSchemes(burstSchemes);

        if (selectedSchemeId) {
          const matchedScheme = burstSchemes.find(
            (scheme) => scheme.scheme_id === selectedSchemeId,
          );
          if (matchedScheme) {
            applySchemeTimeRange(matchedScheme);
          } else {
            setSelectedSchemeId("");
          }
        }

        if (notify) {
          open?.({
            type: "success",
            message: "方案列表已刷新",
            description: `当前可选爆管分析方案 ${burstSchemes.length} 个`,
          });
        }
      } catch (error: any) {
        open?.({
          type: "error",
          message: "刷新方案失败",
          description:
            error?.response?.data?.detail ?? error?.message ?? "无法获取爆管分析方案列表",
        });
      } finally {
        setSchemeLoading(false);
      }
    },
    [applySchemeTimeRange, open, schemeLoading, schemes.length, selectedSchemeId],
  );

  const handleDataSourceChange = (value: "monitoring" | "simulation") => {
    setDataSource(value);
    if (value === "simulation") {
      void fetchSchemes();
    }
  };

  const handleSchemeSelect = (schemeId: number) => {
    setSelectedSchemeId(schemeId);
    const scheme = schemes.find((item) => item.scheme_id === schemeId);
    if (scheme) {
      applySchemeTimeRange(scheme);
    }
  };

  const timeWindowValid = useMemo(() => {
    if (!scadaStart || !scadaEnd) return false;
    return scadaEnd.diff(scadaStart, "day", true) >= 2;
  }, [scadaEnd, scadaStart]);

  const contaminationValue = useMemo(() => {
    const normalized = contaminationInput.trim().toLowerCase();
    if (!normalized || normalized === "auto") {
      return "auto" as const;
    }
    const parsed = Number(normalized);
    if (!Number.isFinite(parsed) || parsed <= 0 || parsed >= 0.5) {
      return null;
    }
    return parsed;
  }, [contaminationInput]);

  const isValid =
    Boolean(scadaStart && scadaEnd) &&
    timeWindowValid &&
    Number.isFinite(mu) &&
    mu > 0 &&
    Number.isFinite(pointsPerDay) &&
    pointsPerDay > 0 &&
    Number.isFinite(nEstimators) &&
    nEstimators > 0 &&
    contaminationValue !== null &&
    (dataSource !== "simulation" || Boolean(selectedSchemeId));

  const handleRun = async () => {
    if (!isValid || !scadaStart || !scadaEnd || contaminationValue === null) {
      open?.({
        type: "error",
        message: "参数不完整",
        description: "请检查时间范围（至少2天）和高级参数是否填写正确。",
      });
      return;
    }

    setRunning(true);
    open?.({
      key: "burst-detection-analysis-progress",
      type: "progress",
      message: "正在执行爆管侦测",
      description: "正在读取数据并计算异常分数。",
      undoableTimeout: 3,
    });

    try {
      const selectedScheme =
        dataSource === "simulation"
          ? schemes.find((item) => item.scheme_id === selectedSchemeId)
          : undefined;

      const response = await api.post("/api/v1/burst-detection/detect/", {
        network: NETWORK_NAME,
        data_source: dataSource,
        scheme_name: schemeName.trim() || undefined,
        scada_start: scadaStart.toISOString(),
        scada_end: scadaEnd.toISOString(),
        mu,
        points_per_day: pointsPerDay,
        iforest_params: {
          n_estimators: nEstimators,
          contamination: contaminationValue,
        },
        simulation_scheme_name: selectedScheme?.scheme_name,
        simulation_scheme_type: selectedScheme?.scheme_type,
      });

      onResult({
        ...(response.data as BurstDetectionResult),
        scheme_name: schemeName.trim() || (response.data as BurstDetectionResult).scheme_name,
        algorithm_params: {
          mu,
          points_per_day: pointsPerDay,
          iforest_params: {
            n_estimators: nEstimators,
            contamination: contaminationValue,
          },
        },
      });

      open?.({
        key: "burst-detection-analysis-success",
        type: "success",
        message: "爆管侦测完成",
        description: `共识别 ${response.data.summary?.anomaly_day_count ?? 0} 个异常日。`,
      });
    } catch (error: any) {
      open?.({
        key: "burst-detection-analysis-error",
        type: "error",
        message: "侦测失败",
        description: error?.response?.data?.detail ?? error?.message ?? "请求失败",
      });
    } finally {
      setRunning(false);
    }
  };

  return (
    <Box className="flex flex-col flex-1 min-h-0">
      <Box className="flex flex-col gap-3">
        <Box>
          <Typography variant="subtitle2" className="mb-1 font-medium">
            方案名称
          </Typography>
          <TextField
            value={schemeName}
            onChange={(event) => setSchemeName(event.target.value)}
            placeholder="请输入方案名称"
            fullWidth
            size="small"
          />
        </Box>

        <Box>
          <Typography variant="subtitle2" className="mb-1 font-medium">
            数据来源
          </Typography>
          <FormControl fullWidth size="small">
            <Select
              value={dataSource}
              onChange={(e) => handleDataSourceChange(e.target.value as "monitoring" | "simulation")}
            >
              <MenuItem value="monitoring">监测数据</MenuItem>
              <MenuItem value="simulation">模拟方案</MenuItem>
            </Select>
          </FormControl>
        </Box>

        {isSimulationMode && (
          <Box>
            <Typography variant="subtitle2" className="mb-1 font-medium">
              选择爆管分析方案
            </Typography>
            <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
              <FormControl fullWidth size="small">
                <Select
                  value={selectedSchemeId}
                  onChange={(e) => handleSchemeSelect(Number(e.target.value))}
                  disabled={schemeLoading}
                  displayEmpty
                >
                  <MenuItem value="" disabled>
                    请选择方案
                  </MenuItem>
                  {schemes.map((scheme) => (
                    <MenuItem key={scheme.scheme_id} value={scheme.scheme_id}>
                      {scheme.scheme_name}
                    </MenuItem>
                  ))}
                </Select>
              </FormControl>
              <IconButton
                size="small"
                color="primary"
                onClick={() => void fetchSchemes({ force: true, notify: true })}
                disabled={schemeLoading}
                aria-label="刷新爆管分析方案"
                sx={{
                  border: "1px solid",
                  borderColor: "divider",
                  borderRadius: 1,
                }}
              >
                {schemeLoading ? (
                  <CircularProgress size={18} color="inherit" />
                ) : (
                  <RefreshIcon fontSize="small" />
                )}
              </IconButton>
            </Box>
          </Box>
        )}

        <LocalizationProvider
          dateAdapter={AdapterDayjs}
          adapterLocale="zh-cn"
          localeText={pickerZhCN.components.MuiLocalizationProvider.defaultProps.localeText}
        >
          <Box className="grid grid-cols-2 gap-2">
            <Box>
              <Typography variant="subtitle2" className="mb-1 font-medium">
                侦测开始时间
              </Typography>
              <DateTimePicker
                value={scadaStart}
                onChange={setScadaStart}
                maxDateTime={scadaEnd ? scadaEnd.subtract(2, "day") : undefined}
                disabled={isSimulationMode}
                format="YYYY-MM-DD HH:mm"
                slotProps={{ textField: { size: "small", fullWidth: true } }}
              />
            </Box>
            <Box>
              <Typography variant="subtitle2" className="mb-1 font-medium">
                侦测结束时间
              </Typography>
              <DateTimePicker
                value={scadaEnd}
                onChange={setScadaEnd}
                minDateTime={scadaStart ? scadaStart.add(2, "day") : undefined}
                disabled={isSimulationMode}
                format="YYYY-MM-DD HH:mm"
                slotProps={{ textField: { size: "small", fullWidth: true } }}
              />
            </Box>
          </Box>
        </LocalizationProvider>

        <Box className="rounded-lg border border-blue-100 bg-blue-50 px-3 py-2 text-sm text-blue-900">
          当前页面为展示版：手动触发一次侦测，展示异常日、最新测点排名和结果表格，不做定时轮询。
        </Box>

        <Box
          sx={{
            border: "1px solid",
            borderColor: "grey.200",
            borderRadius: 1,
            overflow: "hidden",
          }}
        >
          <Box
            role="button"
            tabIndex={0}
            onClick={() => setAdvancedOpen((prev) => !prev)}
            onKeyDown={(event) => {
              if (event.key === "Enter" || event.key === " ") {
                setAdvancedOpen((prev) => !prev);
              }
            }}
            sx={{
              display: "flex",
              alignItems: "center",
              justifyContent: "space-between",
              px: 1.25,
              py: 0.75,
              cursor: "pointer",
              backgroundColor: "transparent",
              "&:hover": { backgroundColor: "action.hover" },
            }}
          >
            <Typography variant="body2" color="text.secondary">
              高级参数
            </Typography>
            <ExpandMoreIcon
              sx={{
                transform: advancedOpen ? "rotate(180deg)" : "rotate(0deg)",
                transition: "transform 0.2s ease",
              }}
            />
          </Box>
          <Collapse in={advancedOpen} timeout="auto" unmountOnExit>
            <Box
              sx={{
                px: 1.25,
                pt: 1.25,
                pb: 1.25,
                backgroundColor: "transparent",
              }}
            >
              <Box className="flex flex-col gap-3">
                <TextField
                  type="number"
                  label="频域截断系数"
                  value={mu}
                  onChange={(event) => setMu(Number(event.target.value))}
                  size="small"
                  fullWidth
                  inputProps={{ min: 1 }}
                />
                <TextField
                  type="number"
                  label="每日采样点数"
                  value={pointsPerDay}
                  onChange={(event) => setPointsPerDay(Number(event.target.value))}
                  size="small"
                  fullWidth
                  inputProps={{ min: 1 }}
                />
                <TextField
                  type="number"
                  label="孤立森林树数量"
                  value={nEstimators}
                  onChange={(event) => setNEstimators(Number(event.target.value))}
                  size="small"
                  fullWidth
                  inputProps={{ min: 1 }}
                />
                <TextField
                  label="异常比例"
                  value={contaminationInput}
                  onChange={(event) => setContaminationInput(event.target.value)}
                  size="small"
                  fullWidth
                  helperText="填写 auto 或 0~0.5 之间的小数。"
                  error={contaminationValue === null}
                />
              </Box>
            </Box>
          </Collapse>
        </Box>
      </Box>

      <Box className="mt-auto pt-3 flex gap-2">
        <Button
          variant="outlined"
          fullWidth
          disabled={running}
          sx={{ textTransform: "none", fontWeight: 500 }}
          onClick={() => {
            setSchemeName(`Burst_Detection_${Date.now()}`);
            setScadaStart(dayjs().subtract(3, "day"));
            setScadaEnd(dayjs());
            setMu(100);
            setPointsPerDay(96);
            setNEstimators(50);
            setContaminationInput("auto");
          }}
        >
          重置
        </Button>
        <Button
          variant="contained"
          fullWidth
          disabled={!isValid || running}
          onClick={handleRun}
          className="bg-blue-600 hover:bg-blue-700"
          sx={{ textTransform: "none", fontWeight: 500 }}
        >
          {running ? <CircularProgress size={20} color="inherit" /> : "开始侦测"}
        </Button>
      </Box>
    </Box>
  );
};

export default AnalysisParameters;
