"use client";

import React, { useCallback, useMemo, useState } from "react";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import RefreshIcon from "@mui/icons-material/Refresh";
import {
  Alert,
  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 { useControllableObjectState } from "@components/olmap/core/useControllableState";
import { FLOW_DISPLAY_UNIT, toM3s } from "@utils/units";
import { BurstLocationResult } from "./types";
import { getBurstLocationErrorNotice } from "./burstLocationError";

interface Props {
  onResult: (result: BurstLocationResult) => void;
  state?: BurstLocationAnalysisParametersState;
  onStateChange?: (state: BurstLocationAnalysisParametersState) => void;
}

export interface SchemeItem {
  scheme_id: number;
  scheme_name: string;
  scheme_type: string;
  create_time: string;
  scheme_start_time: string;
  scheme_detail?: {
    modify_total_duration: number;
    burst_ID?: string[] | string;
  };
}

type DataSource = "monitoring" | "simulation";

export interface BurstLocationAnalysisParametersState {
  schemeName: string;
  dataSource: DataSource;
  schemes: SchemeItem[];
  selectedSchemeId: number | "";
  burstLeakage: number;
  enableFlow: boolean;
  burstStartTime: Dayjs | null;
  burstEndTime: Dayjs | null;
  minDpressure: number;
  basicPressure: number;
  advancedOpen: boolean;
}

export const createBurstLocationAnalysisParametersState =
  (): BurstLocationAnalysisParametersState => ({
    schemeName: `Burst_Locate_${Date.now()}`,
    dataSource: "monitoring",
    schemes: [],
    selectedSchemeId: "",
    burstLeakage: 1440,
    enableFlow: false,
    burstStartTime: dayjs().subtract(20, "minute"),
    burstEndTime: dayjs().subtract(5, "minute"),
    minDpressure: 2,
    basicPressure: 10,
    advancedOpen: false,
  });

const AnalysisParameters: React.FC<Props> = ({
  onResult,
  state,
  onStateChange,
}) => {
  const { open } = useNotification();
  const [parametersState, setParametersState, setFormField] = useControllableObjectState(
    state,
    onStateChange,
    createBurstLocationAnalysisParametersState(),
  );
  const {
    schemeName,
    dataSource,
    schemes,
    selectedSchemeId,
    burstLeakage,
    enableFlow,
    burstStartTime,
    burstEndTime,
    minDpressure,
    basicPressure,
    advancedOpen,
  } = parametersState;
  const [schemeLoading, setSchemeLoading] = 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");

    setParametersState((previous) => ({
      ...previous,
      burstStartTime: start,
      burstEndTime: end,
    }));
  }, [setParametersState]);

  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: { scheme_type: "burst_analysis" },
        });
        const burstSchemes = (response.data as SchemeItem[]).filter(
          (scheme) => scheme.scheme_type === "burst_analysis",
        ).sort(
          (a, b) =>
            dayjs(b.create_time).valueOf() - dayjs(a.create_time).valueOf(),
        );

        setFormField("schemes", burstSchemes);

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

        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, setFormField],
  );

  const handleDataSourceChange = (value: DataSource) => {
    setFormField("dataSource", value);
    if (value === "simulation") {
      void fetchSchemes();
    }
  };

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

  const isValid = useMemo(() => {
    if (!Number.isFinite(burstLeakage) || burstLeakage <= 0) return false;
    if (!burstStartTime || !burstEndTime) {
      return false;
    }
    if (dataSource === "simulation" && !selectedSchemeId) {
      return false;
    }

    return burstStartTime.isBefore(burstEndTime);
  }, [
    burstLeakage,
    burstStartTime,
    burstEndTime,
    dataSource,
    selectedSchemeId,
  ]);

  const handleRun = async () => {
    if (!isValid || !burstStartTime || !burstEndTime) {
      open?.({ type: "error", message: "请完善参数并确认时间范围合法" });
      return;
    }

    setRunning(true);
    open?.({
      key: "burst-location-analysis-progress",
      type: "progress",
      message: "方案提交分析中",
      undoableTimeout: 3,
    });

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

      const response = await api.post(
        `${config.BACKEND_URL}/api/v1/burst-locations`,
        {
          data_source: dataSource,
          scheme_name: schemeName.trim() || undefined,
          burst_leakage: toM3s(burstLeakage, FLOW_DISPLAY_UNIT),
          min_dpressure: minDpressure,
          basic_pressure: basicPressure,
          scada_burst_start: burstStartTime.toISOString(),
          scada_burst_end: burstEndTime.toISOString(),
          use_scada_flow: enableFlow || undefined,
          simulation_scheme_name: selectedScheme?.scheme_name,
          simulation_scheme_type: selectedScheme?.scheme_type,
        },
      );

      const resultPayload = response.data as BurstLocationResult;
      const selectedBurstIds = normalizeBurstIds(selectedScheme?.scheme_detail?.burst_ID);
      onResult(
        selectedBurstIds.length > 0
          ? {
              ...resultPayload,
              simulation_scheme: {
                ...resultPayload.simulation_scheme,
                name: resultPayload.simulation_scheme?.name ?? selectedScheme?.scheme_name,
                type: resultPayload.simulation_scheme?.type ?? selectedScheme?.scheme_type,
                burst_ids:
                  resultPayload.simulation_scheme?.burst_ids?.length
                    ? resultPayload.simulation_scheme.burst_ids
                    : selectedBurstIds,
              },
            }
          : resultPayload,
      );
      open?.({
        key: "burst-location-analysis-success",
        type: "success",
        message: "爆管定位成功",
        description: `定位到管段: ${(response.data as BurstLocationResult).located_pipe}`,
      });
    } catch (error: any) {
      const notice = getBurstLocationErrorNotice(error);
      open?.({
        key: "burst-location-analysis-error",
        type: "error",
        message: notice.message,
        description: notice.description,
      });
    } 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={(e) => setFormField("schemeName", e.target.value)}
            placeholder="请输入方案名称"
            fullWidth
            size="small"
          />
        </Box>

        <Box>
          <Typography variant="subtitle2" className="mb-1 font-medium">
            SCADA 数据来源
          </Typography>
          <FormControl fullWidth size="small">
            <Select
              value={dataSource}
              onChange={(e) => handleDataSourceChange(e.target.value as DataSource)}
            >
              <MenuItem value="monitoring">监测数据</MenuItem>
              <MenuItem value="simulation">模拟方案</MenuItem>
            </Select>
          </FormControl>
          <Alert
            severity={isSimulationMode ? "warning" : "info"}
            variant="outlined"
            sx={{
              mt: 1,
              alignItems: "flex-start",
              borderColor: isSimulationMode ? "warning.light" : "info.light",
              backgroundColor: isSimulationMode ? "#fff8e1" : "#eff6ff",
              "& .MuiAlert-message": { width: "100%" },
            }}
          >
            <Typography
              variant="caption"
              className="block font-semibold"
              sx={{ color: isSimulationMode ? "warning.dark" : "info.dark" }}
            >
              {isSimulationMode ? "模拟方案分析前置条件" : "数据选择规则"}
            </Typography>
            <Typography
              variant="caption"
              className="block leading-5"
              sx={{ color: isSimulationMode ? "warning.dark" : "info.dark" }}
            >
              {isSimulationMode
                ? "爆管数据取所选方案，正常数据取同一时间窗的实时模拟结果。所选时间窗必须已有实时模拟正常基线，否则无法分析；系统不会自动补数据。"
                : "当前为监测数据：爆管数据取所选监测时间窗，正常数据默认取前一天同一时段的监测数据。"}
            </Typography>
          </Alert>
        </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={burstStartTime}
                onChange={(value) => setFormField("burstStartTime", value)}
                maxDateTime={burstEndTime ?? 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={burstEndTime}
                onChange={(value) => setFormField("burstEndTime", value)}
                minDateTime={burstStartTime ?? undefined}
                disabled={isSimulationMode}
                format="YYYY-MM-DD HH:mm"
                slotProps={{ textField: { size: "small", fullWidth: true } }}
              />
            </Box>
          </Box>
        </LocalizationProvider>

        <Box className="flex flex-col gap-2">
          <Typography variant="subtitle2" className="mb-1 font-medium">
            爆管漏损流量 ({FLOW_DISPLAY_UNIT})
          </Typography>
          <TextField
            type="number"
            size="small"
            value={burstLeakage}
            onChange={(e) => {
              const value = Number(e.target.value);
              setFormField("burstLeakage", Number.isNaN(value) ? 1440 : Math.max(0, value));
            }}
            fullWidth
            inputProps={{ min: 0, step: 10 }}
          />
          <Box
            sx={{
              border: "1px solid",
              borderColor: "grey.200",
              borderRadius: 1,
              overflow: "hidden",
            }}
          >
            <Box
              role="button"
              tabIndex={0}
              onClick={() => setFormField("advancedOpen", !advancedOpen)}
              onKeyDown={(e) => {
                if (e.key === "Enter" || e.key === " ") setFormField("advancedOpen", !advancedOpen);
              }}
              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">
                  <Box>
                    <Typography variant="subtitle2" className="mb-1 font-medium">
                      流量校核
                    </Typography>
                    <FormControl fullWidth size="small">
                      <Select
                        value={enableFlow ? "enabled" : "disabled"}
                        onChange={(e) => setFormField("enableFlow", e.target.value === "enabled")}
                      >
                        <MenuItem value="disabled">禁用</MenuItem>
                        <MenuItem value="enabled">启用（使用流量计）</MenuItem>
                      </Select>
                    </FormControl>
                  </Box>
                  <Box className="grid grid-cols-2 gap-2">
                    <TextField
                      type="number"
                      label="最小压降 (m)"
                      size="small"
                      value={minDpressure}
                      onChange={(e) => setFormField("minDpressure", Number(e.target.value))}
                    />
                    <TextField
                      type="number"
                      label="基础压力 (m)"
                      size="small"
                      value={basicPressure}
                      onChange={(e) => setFormField("basicPressure", Number(e.target.value))}
                    />
                  </Box>
                </Box>
              </Box>
            </Collapse>
          </Box>
        </Box>
      </Box>

      <Box className="mt-auto pt-3">
        <Button
          fullWidth
          variant="contained"
          onClick={handleRun}
          disabled={!isValid || running}
          className="bg-blue-600 hover:bg-blue-700"
        >
          {running ? "定位中..." : "开始定位"}
        </Button>
      </Box>
    </Box>
  );
};

export default AnalysisParameters;

const normalizeBurstIds = (value: string[] | string | undefined) => {
  if (!value) return [];
  const values = Array.isArray(value) ? value : [value];
  return Array.from(
    new Set(values.map((item) => String(item).trim()).filter(Boolean)),
  );
};
