"use client";

import React, { useCallback, useState } from "react";
import {
  Box,
  Button,
  Chip,
  Paper,
  Stack,
  Typography,
  alpha,
  useTheme,
} from "@mui/material";
import LocationOnRounded from "@mui/icons-material/LocationOnRounded";
import TimelineRounded from "@mui/icons-material/TimelineRounded";
import SensorsRounded from "@mui/icons-material/SensorsRounded";
import CheckCircleRounded from "@mui/icons-material/CheckCircleRounded";

import {
  useChatToolStore,
  type ChatToolAction,
} from "@/store/chatToolStore";
import type { ToolCall } from "./chatMessageSections";

/* ------------------------------------------------------------------ */
/*  Interactive card rendered inside a chat bubble for tool actions    */
/*  (locate nodes/pipes, open history/SCADA panels).                  */
/* ------------------------------------------------------------------ */

type ToolMeta = {
  label: string;
  icon: React.ReactNode;
  actionLabel: string;
  color: string;
};

const LOCATE_TOOL_TO_LAYER: Record<string, string> = {
  locate_features: "",
  locate_junctions: "geo_junctions_mat",
  locate_pipes: "geo_pipes_mat",
  locate_valves: "geo_valves",
  locate_reservoirs: "geo_reservoirs",
  locate_pumps: "geo_pumps",
  locate_tanks: "geo_tanks",
};

const LOCATE_LINE_TOOLS = new Set<string>(["locate_pipes"]);

const TOOL_META: Record<string, ToolMeta> = {
  locate_features: {
    label: "定位要素",
    icon: <LocationOnRounded sx={{ fontSize: 18 }} />,
    actionLabel: "定位到地图",
    color: "#5470c6",
  },
  locate_junctions: {
    label: "定位节点",
    icon: <LocationOnRounded sx={{ fontSize: 18 }} />,
    actionLabel: "定位到地图",
    color: "#5470c6",
  },
  locate_pipes: {
    label: "定位管道",
    icon: <LocationOnRounded sx={{ fontSize: 18 }} />,
    actionLabel: "定位到地图",
    color: "#91cc75",
  },
  locate_valves: {
    label: "定位阀门",
    icon: <LocationOnRounded sx={{ fontSize: 18 }} />,
    actionLabel: "定位到地图",
    color: "#9a60b4",
  },
  locate_reservoirs: {
    label: "定位水源",
    icon: <LocationOnRounded sx={{ fontSize: 18 }} />,
    actionLabel: "定位到地图",
    color: "#ea7ccc",
  },
  locate_pumps: {
    label: "定位泵站",
    icon: <LocationOnRounded sx={{ fontSize: 18 }} />,
    actionLabel: "定位到地图",
    color: "#fc8452",
  },
  locate_tanks: {
    label: "定位水池",
    icon: <LocationOnRounded sx={{ fontSize: 18 }} />,
    actionLabel: "定位到地图",
    color: "#3ba272",
  },
  view_history: {
    label: "查看计算结果",
    icon: <TimelineRounded sx={{ fontSize: 18 }} />,
    actionLabel: "查看曲线",
    color: "#fac858",
  },
  view_scada: {
    label: "查看监测数据",
    icon: <SensorsRounded sx={{ fontSize: 18 }} />,
    actionLabel: "查看数据",
    color: "#ee6666",
  },
  show_chart: {
    label: "显示图表",
    icon: <TimelineRounded sx={{ fontSize: 18 }} />,
    actionLabel: "显示",
    color: "#73c0de",
  },
};

/* ---------- helpers ---------- */

function getToolDescription(toolCall: ToolCall): string {
  const { params } = toolCall;
  const normalizeIds = (): string[] => {
    const rawIds = params.ids;
    if (Array.isArray(rawIds)) {
      return rawIds.map((id) => String(id)).filter((id) => id.trim().length > 0);
    }
    if (typeof rawIds === "string") {
      return rawIds
        .split(",")
        .map((id) => id.trim())
        .filter(Boolean);
    }
    return [];
  };
  const resolveScadaFeatureInfos = (): [string, string][] => {
    const rawFeatureInfos = params.feature_infos;
    if (Array.isArray(rawFeatureInfos)) {
      const normalizedFeatureInfos = rawFeatureInfos
        .map((item) => (Array.isArray(item) ? item : null))
        .filter((item): item is [unknown, unknown] => Boolean(item))
        .map(
          (item) =>
            [String(item[0] ?? ""), String(item[1] ?? "scada")] as [
              string,
              string,
            ],
        )
        .filter(([id]) => id.trim().length > 0);
      if (normalizedFeatureInfos.length > 0) {
        return normalizedFeatureInfos;
      }
    }

    const rawDeviceIds =
      params.device_ids ??
      params.deviceId ??
      params.device_id ??
      params.id ??
      params.ids;
    const deviceIds = Array.isArray(rawDeviceIds)
      ? rawDeviceIds.map((id) => String(id))
      : typeof rawDeviceIds === "string"
        ? rawDeviceIds
            .split(",")
            .map((id) => id.trim())
            .filter(Boolean)
        : [];

    return deviceIds.map((id) => [id, "scada"]);
  };
  const resolveTimeRange = () => ({
    startTime:
      (params.start_time as string | undefined) ??
      (params.startTime as string | undefined) ??
      (params.from as string | undefined) ??
      (params.start as string | undefined),
    endTime:
      (params.end_time as string | undefined) ??
      (params.endTime as string | undefined) ??
      (params.to as string | undefined) ??
      (params.end as string | undefined),
  });
  const resolveLocateFeatureType = (): string => {
    const rawType = params.feature_type;
    if (typeof rawType === "string" && rawType.trim()) {
      return rawType.trim().toLowerCase();
    }
    return "";
  };
  switch (toolCall.tool) {
    case "locate_features":
    case "locate_junctions":
    case "locate_pipes":
    case "locate_valves":
    case "locate_reservoirs":
    case "locate_pumps":
    case "locate_tanks": {
      const ids = normalizeIds();
      const idsText =
        ids.length > 3
        ? `${ids.slice(0, 3).join(", ")} 等 ${ids.length} 个`
        : ids.join(", ");
      if (toolCall.tool !== "locate_features") {
        return idsText;
      }
      const featureType = resolveLocateFeatureType();
      if (!featureType) {
        return idsText;
      }
      return idsText
        ? `${featureType} · ${idsText}`
        : featureType;
    }
    case "view_history":
    case "view_scada": {
      const infos =
        toolCall.tool === "view_scada"
          ? resolveScadaFeatureInfos()
          : ((params.feature_infos as [string, string][] | undefined) ?? []);
      const names = infos.map(([id]) => id);
      const base =
        names.length > 3
          ? `${names.slice(0, 3).join(", ")} 等 ${names.length} 个`
          : names.join(", ");
      const { startTime, endTime } = resolveTimeRange();
      if (!startTime && !endTime) {
        return base;
      }
      const rangeLabel = `时间段: ${startTime ?? "--"} ~ ${endTime ?? "--"}`;
      return base ? `${base} · ${rangeLabel}` : rangeLabel;
    }
    case "show_chart": {
      return (params.title as string | undefined) ?? "数据图表";
    }
    default:
      return "";
  }
}

function buildAction(toolCall: ToolCall): ChatToolAction | null {
  const { params } = toolCall;
  const normalizeIds = (): string[] => {
    const rawIds = params.ids;
    if (Array.isArray(rawIds)) {
      return rawIds.map((id) => String(id)).filter((id) => id.trim().length > 0);
    }
    if (typeof rawIds === "string") {
      return rawIds
        .split(",")
        .map((id) => id.trim())
        .filter(Boolean);
    }
    return [];
  };
  const resolveScadaFeatureInfos = (): [string, string][] => {
    const rawFeatureInfos = params.feature_infos;
    if (Array.isArray(rawFeatureInfos)) {
      const normalizedFeatureInfos = rawFeatureInfos
        .map((item) => (Array.isArray(item) ? item : null))
        .filter((item): item is [unknown, unknown] => Boolean(item))
        .map(
          (item) =>
            [String(item[0] ?? ""), String(item[1] ?? "scada")] as [
              string,
              string,
            ],
        )
        .filter(([id]) => id.trim().length > 0);
      if (normalizedFeatureInfos.length > 0) {
        return normalizedFeatureInfos;
      }
    }

    const rawDeviceIds =
      params.device_ids ??
      params.deviceId ??
      params.device_id ??
      params.id ??
      params.ids;
    const deviceIds = Array.isArray(rawDeviceIds)
      ? rawDeviceIds.map((id) => String(id))
      : typeof rawDeviceIds === "string"
        ? rawDeviceIds
            .split(",")
            .map((id) => id.trim())
            .filter(Boolean)
        : [];

    return deviceIds.map((id) => [id, "scada"]);
  };
  const resolveTimeRange = () => ({
    startTime:
      (params.start_time as string | undefined) ??
      (params.startTime as string | undefined) ??
      (params.from as string | undefined) ??
      (params.start as string | undefined),
    endTime:
      (params.end_time as string | undefined) ??
      (params.endTime as string | undefined) ??
      (params.to as string | undefined) ??
      (params.end as string | undefined),
  });
  switch (toolCall.tool) {
    case "locate_features": {
      const featureTypeRaw = params.feature_type;
      const featureType =
        typeof featureTypeRaw === "string"
          ? featureTypeRaw.trim().toLowerCase()
          : "";
      const config = locateFeatureTypeToConfig(featureType);
      if (!config) return null;
      return {
        type: "locate_features",
        ids: normalizeIds(),
        layer: config.layer,
        geometryKind: config.geometryKind,
      };
    }
    case "locate_junctions":
    case "locate_pipes":
    case "locate_valves":
    case "locate_reservoirs":
    case "locate_pumps":
    case "locate_tanks": {
      const layer = LOCATE_TOOL_TO_LAYER[toolCall.tool];
      if (!layer) return null;
      return {
        type: "locate_features",
        ids: normalizeIds(),
        layer,
        geometryKind: LOCATE_LINE_TOOLS.has(toolCall.tool) ? "line" : "point",
      };
    }
    case "view_history": {
      const historyRange = resolveTimeRange();
      return {
        type: "view_history",
        featureInfos:
          (params.feature_infos as [string, string][] | undefined) ?? [],
        dataType:
          (params.data_type as "realtime" | "scheme" | "none" | undefined) ??
          "realtime",
        startTime: historyRange.startTime,
        endTime: historyRange.endTime,
      };
    }
    case "view_scada": {
      const scadaRange = resolveTimeRange();
      return {
        type: "view_scada",
        featureInfos: resolveScadaFeatureInfos(),
        startTime: scadaRange.startTime,
        endTime: scadaRange.endTime,
      };
    }
    case "show_chart":
      return {
        type: "show_chart",
        title: params.title as string | undefined,
        chartType:
          (params.chart_type as "line" | "bar" | "pie" | undefined) ?? "line",
        xData: (params.x_data as string[] | undefined) ?? [],
        series:
          (params.series as
            | Array<{ name: string; data: number[]; type?: "line" | "bar" }>
            | undefined) ?? [],
        xAxisName: params.x_axis_name as string | undefined,
        yAxisName: params.y_axis_name as string | undefined,
      };
    default:
      return null;
  }
}

/* ---------- component ---------- */

export interface ChatToolCallBlockProps {
  toolCall: ToolCall;
}

export const ChatToolCallBlock: React.FC<ChatToolCallBlockProps> = ({
  toolCall,
}) => {
  const theme = useTheme();
  const dispatch = useChatToolStore((s) => s.dispatch);
  const [executed, setExecuted] = useState(false);

  const meta: ToolMeta = TOOL_META[toolCall.tool] ?? {
    label: toolCall.tool,
    icon: null,
    actionLabel: "执行",
    color: theme.palette.primary.main,
  };

  const description = getToolDescription(toolCall);

  const handleExecute = useCallback(() => {
    const action = buildAction(toolCall);
    if (action) {
      dispatch(action);
      setExecuted(true);
    }
  }, [toolCall, dispatch]);

  return (
    <Paper
      elevation={0}
      sx={{
        mt: 1.5,
        mb: 1,
        p: 1.5,
        borderRadius: 3,
        border: `1px solid ${alpha(meta.color, 0.25)}`,
        bgcolor: alpha(meta.color, 0.04),
      }}
    >
      <Stack direction="row" alignItems="center" spacing={1.5}>
        {/* Icon */}
        <Box
          sx={{
            width: 32,
            height: 32,
            borderRadius: 2,
            bgcolor: alpha(meta.color, 0.12),
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            color: meta.color,
            flexShrink: 0,
          }}
        >
          {meta.icon}
        </Box>

        {/* Description */}
        <Box sx={{ flex: 1, minWidth: 0 }}>
          <Typography
            variant="caption"
            sx={{
              fontWeight: 600,
              color: "text.primary",
              display: "block",
            }}
          >
            {meta.label}
          </Typography>
          {description && (
            <Typography
              variant="caption"
              sx={{
                color: "text.secondary",
                fontSize: "0.75rem",
                display: "block",
                overflow: "hidden",
                textOverflow: "ellipsis",
                whiteSpace: "nowrap",
              }}
            >
              {description}
            </Typography>
          )}
        </Box>

        {/* Action */}
        {executed ? (
          <Chip
            icon={<CheckCircleRounded sx={{ fontSize: 16 }} />}
            label="已执行"
            size="small"
            sx={{
              bgcolor: alpha("#4caf50", 0.1),
              color: "#4caf50",
              fontWeight: 600,
              fontSize: "0.75rem",
            }}
          />
        ) : (
          <Button
            size="small"
            variant="outlined"
            onClick={handleExecute}
            sx={{
              borderColor: alpha(meta.color, 0.4),
              color: meta.color,
              fontWeight: 600,
              fontSize: "0.75rem",
              borderRadius: 2,
              textTransform: "none",
              whiteSpace: "nowrap",
              "&:hover": {
                borderColor: meta.color,
                bgcolor: alpha(meta.color, 0.08),
              },
            }}
          >
            {meta.actionLabel}
          </Button>
        )}
      </Stack>
    </Paper>
  );
};
  const locateFeatureTypeToConfig = (
    featureType: string,
  ): { layer: string; geometryKind: "point" | "line" } | null => {
    switch (featureType) {
      case "junction":
      case "junctions":
        return { layer: "geo_junctions_mat", geometryKind: "point" };
      case "pipe":
      case "pipes":
        return { layer: "geo_pipes_mat", geometryKind: "line" };
      case "valve":
      case "valves":
        return { layer: "geo_valves", geometryKind: "point" };
      case "reservoir":
      case "reservoirs":
        return { layer: "geo_reservoirs", geometryKind: "point" };
      case "pump":
      case "pumps":
        return { layer: "geo_pumps", geometryKind: "point" };
      case "tank":
      case "tanks":
        return { layer: "geo_tanks", geometryKind: "point" };
      default:
        return null;
    }
  };
