"use client";

import React, { useMemo, useState } from "react";
import {
  Box,
  Button,
  Card,
  CardContent,
  Checkbox,
  Chip,
  Collapse,
  FormControlLabel,
  IconButton,
  Tooltip,
  Typography,
} from "@mui/material";
import { InfoOutlined as InfoIcon } from "@mui/icons-material";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import dayjs, { Dayjs } from "dayjs";
import "dayjs/locale/zh-cn";
import { useNotification } from "@refinedev/core";
import { api } from "@/lib/api";
import { NETWORK_NAME } from "@config/config";
import { useControllableObjectState } from "@components/olmap/core/useControllableState";
import { SchemeQueryEmptyState } from "@components/olmap/common/PanelEmptyState";
import {
  BurstDetectionResult,
  BurstDetectionSchemeDetail,
  BurstDetectionSchemeRecord,
} from "./types";

interface Props {
  onViewResult: (result: BurstDetectionResult) => void;
  schemes?: BurstDetectionSchemeRecord[];
  onSchemesChange?: (schemes: BurstDetectionSchemeRecord[]) => void;
  state?: BurstDetectionSchemeQueryState;
  onStateChange?: (state: BurstDetectionSchemeQueryState) => void;
}

export interface BurstDetectionSchemeQueryState {
  queryAll: boolean;
  queryDate: Dayjs | null;
  expandedId: number | null;
  hasQueried: boolean;
}

export const createBurstDetectionSchemeQueryState =
  (): BurstDetectionSchemeQueryState => ({
    queryAll: true,
    queryDate: dayjs(),
    expandedId: null,
    hasQueried: false,
  });

const SchemeQuery: React.FC<Props> = ({
  onViewResult,
  schemes: externalSchemes,
  onSchemesChange,
  state,
  onStateChange,
}) => {
  const { open } = useNotification();
  const [queryState, , setQueryField] = useControllableObjectState(
    state,
    onStateChange,
    createBurstDetectionSchemeQueryState(),
  );
  const { queryAll, queryDate, expandedId, hasQueried } = queryState;
  const [internalSchemes, setInternalSchemes] = useState<BurstDetectionSchemeRecord[]>([]);
  const [loading, setLoading] = useState(false);
  const schemes = externalSchemes !== undefined ? externalSchemes : internalSchemes;
  const setSchemes = onSchemesChange || setInternalSchemes;
  const sortedSchemes = useMemo(
    () =>
      schemes
        .slice()
        .sort(
          (a, b) =>
            dayjs(b.create_time).valueOf() - dayjs(a.create_time).valueOf(),
        ),
    [schemes],
  );

  const buildDisplayResult = (
    scheme: Pick<BurstDetectionSchemeRecord, "scheme_name" | "username" | "create_time">,
    detail?: BurstDetectionSchemeDetail,
  ): BurstDetectionResult | null => {
    const payload = detail?.result_payload;
    const summary = detail?.result_summary;
    const fallbackLatestDay = summary?.latest_day;

    if (!payload && !summary) return null;

    return {
      network: payload?.network ?? detail?.network ?? NETWORK_NAME,
      sensor_nodes: payload?.sensor_nodes ?? detail?.sensor_nodes ?? [],
      observed_source: payload?.observed_source ?? detail?.observed_source ?? "stored_scheme",
      sample_count: payload?.sample_count ?? 0,
      points_per_day: payload?.points_per_day ?? detail?.algorithm_params?.points_per_day ?? 1440,
      day_count: payload?.day_count ?? payload?.rows?.length ?? 0,
      rows: payload?.rows ?? (fallbackLatestDay ? [fallbackLatestDay] : []),
      summary:
        payload?.summary ??
        (summary
          ? summary
          : {
              burst_detected: false,
              latest_day: fallbackLatestDay ?? { Day: 0, Score: 0, Prediction: 1, IsBurst: false },
              most_anomalous_day: 0,
              anomaly_days: [],
              anomaly_day_count: 0,
              latest_sensor_rankings: [],
            }),
      scada_window: payload?.scada_window ?? detail?.scada_window,
      scheme_name: payload?.scheme_name ?? scheme.scheme_name,
      username: payload?.username ?? scheme.username,
      create_time: payload?.create_time ?? scheme.create_time,
      algorithm_params: payload?.algorithm_params ?? detail?.algorithm_params,
      requested_target_time: payload?.requested_target_time,
      target_time: payload?.target_time,
      reference_window: payload?.reference_window,
      sampling_interval_minutes: payload?.sampling_interval_minutes,
      daily_scores: payload?.daily_scores,
      data_quality: payload?.data_quality,
    };
  };

  const handleQuery = async () => {
    setLoading(true);
    try {
      const params: Record<string, string> = {
        scheme_type: "burst_detection",
      };
      if (!queryAll && queryDate) {
        params.query_date = queryDate.startOf("day").toISOString();
      }

      const response = await api.get("/api/v1/schemes", { params });
      const nextSchemes = response.data as BurstDetectionSchemeRecord[];
      setSchemes(nextSchemes);
      setQueryField("hasQueried", true);
      open?.({
        type: "success",
        message: "查询成功",
        description: `共找到 ${nextSchemes.length} 条侦测记录。`,
      });
    } catch (error: any) {
      open?.({
        type: "error",
        message: "查询失败",
        description: error?.response?.data?.detail ?? "无法获取侦测方案列表",
      });
    } finally {
      setLoading(false);
    }
  };

  const handleViewSchemeResult = async (schemeName: string) => {
    try {
      const response = await api.get(
        `/api/v1/schemes/${encodeURIComponent(schemeName)}`,
        { params: { scheme_type: "burst_detection" } },
      );
      const schemeRecord = response.data as BurstDetectionSchemeRecord & {
        result_payload?: BurstDetectionResult;
      };
      const normalizedResult =
        schemeRecord.result_payload ??
        buildDisplayResult(
          {
            scheme_name: schemeRecord.scheme_name,
            username: schemeRecord.username,
            create_time: schemeRecord.create_time,
          },
          schemeRecord.scheme_detail,
        );

      if (!normalizedResult) {
        throw new Error("方案详情缺少侦测结果数据");
      }

      onViewResult(normalizedResult);
      open?.({
        type: "success",
        message: "方案加载成功",
        description: `已加载方案：${schemeName}`,
      });
    } catch (error: any) {
      open?.({
        type: "error",
        message: "查看详情失败",
        description: error?.response?.data?.detail ?? error?.message ?? "无法获取方案详情",
      });
    }
  };

  return (
    <Box className="flex h-full flex-col">
      <Box className="mb-2 rounded bg-gray-50 p-2">
        <Box className="flex items-center justify-between gap-2">
          <Box className="flex items-center gap-2">
            <FormControlLabel
              control={
                <Checkbox
                  size="small"
                  checked={queryAll}
                  onChange={(event) => {
                    setQueryField("queryAll", event.target.checked);
                    setQueryField("hasQueried", false);
                  }}
                />
              }
              label={<Typography variant="body2">查询全部</Typography>}
              className="m-0"
            />
            <LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="zh-cn">
              <DatePicker
                value={queryDate}
                onChange={(value) => {
                  setQueryField("queryDate", value);
                  setQueryField("hasQueried", false);
                }}
                disabled={queryAll}
                format="YYYY-MM-DD"
                slotProps={{ textField: { size: "small", sx: { width: 180 } } }}
              />
            </LocalizationProvider>
          </Box>
          <Button
            variant="contained"
            onClick={handleQuery}
            disabled={loading}
            size="small"
            className="bg-blue-600 hover:bg-blue-700"
            sx={{ minWidth: 80 }}
          >
            {loading ? "查询中..." : "查询"}
          </Button>
        </Box>
      </Box>

      <Box className="flex-1 overflow-auto">
        {sortedSchemes.length === 0 ? (
          <SchemeQueryEmptyState hasQueried={hasQueried} />
        ) : (
          <Box className="space-y-2 p-2">
            <Typography variant="caption" className="px-2 text-gray-500">
              共 {sortedSchemes.length} 条记录
            </Typography>
            {sortedSchemes.map((scheme) => {
              const summary = scheme.scheme_detail?.result_summary;
              const payload = scheme.scheme_detail?.result_payload;
              const isBurst = payload?.summary?.burst_detected ?? summary?.burst_detected ?? false;
              const anomalyDayCount =
                payload?.summary?.anomaly_day_count ?? summary?.anomaly_day_count ?? 0;
              const mostAnomalousDay =
                payload?.summary?.most_anomalous_day ?? summary?.most_anomalous_day ?? "-";
              const sensorCount = payload?.sensor_nodes?.length ?? scheme.scheme_detail?.sensor_nodes?.length ?? 0;
              const targetTime = payload?.target_time ?? payload?.summary?.target_time;
              const targetScore = payload?.summary?.target_score ?? summary?.target_score;
              const targetRank = payload?.summary?.target_rank ?? summary?.target_rank;

              return (
                <Card key={scheme.scheme_id} variant="outlined" className="transition-shadow hover:shadow-md">
                  <CardContent className="p-3 pb-2 last:pb-3">
                    <Box className="mb-2 flex items-start justify-between gap-2">
                      <Box className="min-w-0 flex-1">
                        <Box className="mb-1 flex items-center gap-2">
                          <Typography
                            variant="body2"
                            className="truncate font-medium"
                            title={scheme.scheme_name}
                          >
                            {scheme.scheme_name}
                          </Typography>
                          <Chip
                            size="small"
                            color={isBurst ? "error" : "success"}
                            variant="outlined"
                            label={isBurst ? "存在异常" : "正常"}
                            className="h-5"
                          />
                        </Box>
                        <Typography variant="caption" className="block text-gray-500">
                          创建时间：{dayjs(scheme.create_time).format("YYYY-MM-DD HH:mm")}
                        </Typography>
                      </Box>
                      <Box className="ml-2 flex gap-1">
                        <Tooltip title={expandedId === scheme.scheme_id ? "收起详情" : "查看详情"}>
                          <IconButton
                            size="small"
                            onClick={() =>
                              setQueryField(
                                "expandedId",
                                expandedId === scheme.scheme_id ? null : scheme.scheme_id,
                              )
                            }
                            color="primary"
                            className="p-1"
                          >
                            <InfoIcon fontSize="small" />
                          </IconButton>
                        </Tooltip>
                      </Box>
                    </Box>

                    <Box className="grid grid-cols-3 gap-2">
                      <Box className="rounded bg-gray-50 p-2">
                        <Typography variant="caption" className="text-gray-500">
                          {targetTime ? "目标时刻" : "异常天数"}
                        </Typography>
                        <Typography variant="body2" className="font-semibold text-gray-900">
                          {targetTime ? dayjs(targetTime).format("MM-DD HH:mm") : anomalyDayCount}
                        </Typography>
                      </Box>
                      <Box className="rounded bg-gray-50 p-2">
                        <Typography variant="caption" className="text-gray-500">
                          {targetTime ? "目标分数" : "最异常日"}
                        </Typography>
                        <Typography variant="body2" className="font-semibold text-gray-900">
                          {targetTime
                            ? typeof targetScore === "number"
                              ? targetScore.toFixed(4)
                              : "-"
                            : isBurst
                              ? typeof mostAnomalousDay === "number"
                                ? `第 ${mostAnomalousDay} 天`
                                : mostAnomalousDay
                              : "无"}
                        </Typography>
                      </Box>
                      <Box className="rounded bg-gray-50 p-2">
                        <Typography variant="caption" className="text-gray-500">
                          {targetTime ? "异常排名" : "测点数"}
                        </Typography>
                        <Typography variant="body2" className="font-semibold text-gray-900">
                          {targetTime && targetRank
                            ? `${targetRank} / ${payload?.day_count ?? 15}`
                            : sensorCount}
                        </Typography>
                      </Box>
                    </Box>

                    <Collapse in={expandedId === scheme.scheme_id}>
                      <Box className="mt-2 border-t border-gray-200 pt-3">
                        <Box className="space-y-2 rounded-md bg-gray-50 px-3 py-2">
                          <Box className="grid grid-cols-[78px_1fr] items-center gap-x-2">
                            <Typography variant="caption" className="text-gray-600">
                              数据来源:
                            </Typography>
                            <Typography variant="caption" className="font-medium text-gray-900">
                              {(() => {
                                const ds = payload?.data_source;
                                const os = payload?.observed_source ?? scheme.scheme_detail?.observed_source;
                                if (ds === "simulation") return "模拟数据";
                                if (ds === "monitoring") return "监测数据";
                                if (os === "simulation_scheme_timerange") return "模拟数据";
                                if (os === "backend_timerange") return "监测数据";
                                if (os === "latest_monitoring") return "最新监测数据";
                                if (os === "historical_monitoring") return "历史监测回放";
                                return os || "-";
                              })()}
                            </Typography>
                          </Box>
                          <Box className="grid grid-cols-[78px_1fr] items-center gap-x-2">
                            <Typography variant="caption" className="text-gray-600">
                              时间窗口:
                            </Typography>
                            <Typography variant="caption" className="font-medium text-gray-900">
                              {payload?.scada_window?.start
                                ? `${dayjs(payload.scada_window.start).format("MM-DD HH:mm")} ~ ${dayjs(
                                    payload.scada_window.end,
                                  ).format("MM-DD HH:mm")}`
                                : "-"}
                            </Typography>
                          </Box>
                          <Box className="grid grid-cols-[78px_1fr] items-center gap-x-2">
                            <Typography variant="caption" className="text-gray-600">
                              侦测口径:
                            </Typography>
                            <Typography variant="caption" className="font-medium text-gray-900">
                              频域系数：{scheme.scheme_detail?.algorithm_params?.mu ?? payload?.algorithm_params?.mu ?? "-"}
                              ，每日采样：
                              {scheme.scheme_detail?.algorithm_params?.points_per_day ??
                                payload?.algorithm_params?.points_per_day ??
                                "-"}
                              点，阈值：
                              {payload?.summary?.score_threshold ?? "-"}
                            </Typography>
                          </Box>
                        </Box>
                        <Box className="border-t border-gray-100 pt-2">
                          <Button
                            variant="contained"
                            fullWidth
                            size="small"
                            className="bg-blue-600 hover:bg-blue-700"
                            sx={{ textTransform: "none", fontWeight: 500 }}
                            onClick={() => handleViewSchemeResult(scheme.scheme_name)}
                          >
                            查看侦测结果
                          </Button>
                        </Box>
                      </Box>
                    </Collapse>
                  </CardContent>
                </Card>
              );
            })}
          </Box>
        )}
      </Box>
    </Box>
  );
};

export default SchemeQuery;
