import { Box, Skeleton } from "@mui/material";

import type { MapSkeletonVariant } from "./mapComponentSkeletonConfig";

const skeletonSx = {
  transform: "none",
  bgcolor: "rgba(37, 125, 212, 0.10)",
  "&::after": {
    background:
      "linear-gradient(90deg, transparent, rgba(37, 125, 212, 0.12), transparent)",
  },
  "@media (prefers-reduced-motion: reduce)": {
    animation: "none",
    "&::after": {
      animation: "none",
    },
  },
} as const;

const Line = ({ width = "44%", height = 18 }: { width?: string; height?: number }) => (
  <Skeleton
    variant="text"
    animation="wave"
    width={width}
    height={height}
    sx={skeletonSx}
  />
);

const Field = () => (
  <Box sx={{ width: "100%" }}>
    <Line width="34%" height={18} />
    <Skeleton
      variant="rounded"
      animation="wave"
      height={40}
      sx={{ ...skeletonSx, mt: 0.5, borderRadius: 1 }}
    />
  </Box>
);

const TwoColumns = ({ children }: { children: React.ReactNode }) => (
  <Box
    sx={{
      display: "grid",
      gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
      gap: 1.5,
    }}
  >
    {children}
  </Box>
);

const Action = ({
  width = "100%",
  height = 40,
  testId,
}: {
  width?: string;
  height?: number;
  testId?: string;
}) => (
  <Skeleton
    data-testid={testId}
    variant="rounded"
    animation="wave"
    width={width}
    height={height}
    sx={{ ...skeletonSx, borderRadius: 1 }}
  />
);

const Notice = ({ testId }: { testId?: string }) => (
  <Box
    data-testid={testId}
    sx={{
      display: "grid",
      gap: 0.5,
      p: 1.5,
      bgcolor: "rgba(37, 125, 212, 0.07)",
      borderRadius: 1,
    }}
  >
    <Line width="58%" height={18} />
    <Line width="88%" height={16} />
  </Box>
);

const SelectionHeader = ({ actionWidth = "34%" }: { actionWidth?: string }) => (
  <Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
    <Box sx={{ flex: 1 }}>
      <Line width="44%" height={20} />
    </Box>
    <Action width={actionWidth} height={32} />
  </Box>
);

const EmptySelection = ({ height = 44 }: { height?: number }) => (
  <Skeleton
    variant="rounded"
    animation="wave"
    height={height}
    sx={{ ...skeletonSx, borderRadius: 1 }}
  />
);

const Divider = () => (
  <Box sx={{ height: 1, flex: "0 0 auto", bgcolor: "rgba(15, 23, 42, 0.08)" }} />
);

const AdvancedRow = ({ testId }: { testId?: string }) => (
  <Box
    data-testid={testId}
    sx={{
      minHeight: 40,
      display: "flex",
      alignItems: "center",
      gap: 1,
      px: 1.25,
      border: "1px solid",
      borderColor: "rgba(15, 23, 42, 0.10)",
      borderRadius: 1,
    }}
  >
    <Box sx={{ flex: 1 }}>
      <Line width="34%" height={18} />
    </Box>
    <Skeleton
      variant="circular"
      animation="wave"
      width={24}
      height={24}
      sx={skeletonSx}
    />
  </Box>
);

const SelectionList = ({ rows = 3 }: { rows?: number }) => (
  <Box
    sx={{
      display: "grid",
      gap: 1,
      p: 1.25,
      bgcolor: "rgba(15, 23, 42, 0.025)",
      borderRadius: 1,
    }}
  >
    {Array.from({ length: rows }, (_, index) => (
      <Box
        key={index}
        sx={{ display: "flex", alignItems: "center", gap: 1 }}
      >
        <Skeleton
          variant="circular"
          animation="wave"
          width={26}
          height={26}
          sx={skeletonSx}
        />
        <Box sx={{ flex: 1 }}>
          <Line width={`${72 - index * 8}%`} height={16} />
        </Box>
        <Skeleton
          variant="rounded"
          animation="wave"
          width={48}
          height={26}
          sx={{ ...skeletonSx, borderRadius: 1 }}
        />
      </Box>
    ))}
  </Box>
);

const AnalysisFormSkeleton = ({ variant }: { variant: MapSkeletonVariant }) => {
  switch (variant) {
    case "burst-detection":
      return (
        <>
          <Box
            data-testid="burst-detection-primary-fields"
            data-layout="vertical"
            sx={{ display: "grid", gap: 1.5 }}
          >
            <Field />
            <Field />
            <Field />
          </Box>
          <Notice />
          <Line width="88%" height={16} />
          <Box sx={{ display: "flex", gap: 1.5, mt: "auto", pt: 1.5 }}>
            <Action />
            <Action />
          </Box>
        </>
      );
    case "burst-location":
      return (
        <>
          <Box
            data-testid="burst-location-primary-fields"
            data-layout="vertical"
            sx={{ display: "grid", gap: 1.5 }}
          >
            <Field />
            <Field />
          </Box>
          <Notice />
          <TwoColumns>
            <Field />
            <Field />
          </TwoColumns>
          <Field />
          <AdvancedRow />
          <Box sx={{ mt: "auto", pt: 1.5 }}>
            <Action />
          </Box>
        </>
      );
    case "burst-simulation":
      return (
        <>
          <Box
            data-testid="burst-simulation-selection"
            sx={{ display: "grid", gap: 1 }}
          >
            <SelectionHeader actionWidth="32%" />
          </Box>
          <Box
            data-testid="burst-simulation-primary-fields"
            data-layout="vertical"
            sx={{ display: "grid", gap: 1.5 }}
          >
            <Field />
            <Field />
            <Field />
          </Box>
          <Box sx={{ mt: "auto", pt: 1.5 }}>
            <Action />
          </Box>
        </>
      );
    case "contaminant-simulation":
      return (
        <>
          <Box
            data-testid="contaminant-simulation-selection"
            sx={{ display: "grid", gap: 1 }}
          >
            <SelectionHeader actionWidth="32%" />
            <EmptySelection />
          </Box>
          <Box
            data-testid="contaminant-simulation-primary-fields"
            data-layout="vertical"
            sx={{ display: "grid", gap: 1.5 }}
          >
            {Array.from({ length: 4 }, (_, index) => (
              <Field key={index} />
            ))}
          </Box>
          <Box sx={{ mt: "auto", pt: 1.5 }}>
            <Action />
          </Box>
        </>
      );
    case "dma-leak-detection":
      return (
        <>
          <Notice testId="dma-notice-skeleton" />
          <Box
            data-testid="dma-primary-fields"
            data-layout="vertical"
            sx={{ display: "grid", gap: 1.5 }}
          >
            {Array.from({ length: 5 }, (_, index) => (
              <Field key={index} />
            ))}
          </Box>
          <AdvancedRow testId="dma-advanced-skeleton" />
          <Box sx={{ mt: "auto", pt: 1.5 }}>
            <Action testId="dma-primary-action-skeleton" />
          </Box>
        </>
      );
    case "flushing-analysis":
      return (
        <>
          <Box
            data-testid="flushing-valve-selection"
            sx={{ display: "grid", gap: 1 }}
          >
            <SelectionHeader actionWidth="32%" />
            <EmptySelection height={192} />
          </Box>
          <Divider />
          <Box
            data-testid="flushing-node-selection"
            sx={{ display: "grid", gap: 1 }}
          >
            <SelectionHeader actionWidth="32%" />
            <EmptySelection height={48} />
          </Box>
          <Divider />
          <Box
            data-testid="flushing-primary-fields"
            data-layout="vertical-vertical-two-columns"
            sx={{ display: "grid", gap: 1.5 }}
          >
            <Field />
            <Field />
            <TwoColumns>
              <Field />
              <Field />
            </TwoColumns>
          </Box>
          <Box sx={{ mt: "auto", pt: 1.5 }}>
            <Action />
          </Box>
        </>
      );
    case "monitoring-place-optimization":
      return (
        <>
          <Box
            data-testid="monitoring-primary-fields"
            data-layout="vertical"
            sx={{ display: "grid", gap: 2 }}
          >
            {Array.from({ length: 5 }, (_, index) => (
              <Field key={index} />
            ))}
          </Box>
          <Box sx={{ display: "flex", justifyContent: "flex-end", mt: 1 }}>
            <Action width="132px" />
          </Box>
        </>
      );
    default:
      return null;
  }
};

const DeviceListSkeleton = ({ cleaning }: { cleaning: boolean }) => (
  <Box
    data-testid={cleaning ? "cleaning-device-content" : "network-device-content"}
    sx={{ display: "grid", gap: 2 }}
  >
    <Skeleton
      variant="rounded"
      animation="wave"
      height={40}
      sx={{ ...skeletonSx, borderRadius: 1 }}
    />
    <Box
      sx={{
        display: "grid",
        gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
        gap: 1,
      }}
    >
      {Array.from({ length: 3 }, (_, index) => (
        <Skeleton
          key={index}
          variant="rounded"
          animation="wave"
          height={38}
          sx={{ ...skeletonSx, borderRadius: 1 }}
        />
      ))}
    </Box>
    <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
      <Box sx={{ flex: 1 }}>
        <Line width="58%" height={16} />
      </Box>
      {cleaning && (
        <Skeleton
          data-testid="cleaning-action-skeleton"
          variant="circular"
          animation="wave"
          width={32}
          height={32}
          sx={skeletonSx}
        />
      )}
      <Skeleton
        variant="circular"
        animation="wave"
        width={32}
        height={32}
        sx={skeletonSx}
      />
    </Box>
    <Box sx={{ height: 1, bgcolor: "rgba(15, 23, 42, 0.08)" }} />
    <SelectionList rows={6} />
  </Box>
);

const RiskChartSkeleton = () => (
  <Box
    data-testid="health-risk-chart-content"
    sx={{ display: "grid", height: "100%", minHeight: 360, gap: 2 }}
  >
    <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
      <Line width="32%" height={18} />
      <Box sx={{ flex: 1 }} />
      <Action width="22%" />
    </Box>
    <Box
      sx={{
        position: "relative",
        display: "flex",
        alignItems: "flex-end",
        justifyContent: "space-around",
        gap: 2,
        minHeight: 300,
        px: 3,
        pt: 3,
        pb: 2,
        bgcolor: "rgba(15, 23, 42, 0.025)",
        borderRadius: 1,
        boxShadow: "inset 0 -1px 0 rgba(15, 23, 42, 0.10)",
      }}
    >
      {[36, 58, 44, 76, 62, 84].map((height, index) => (
        <Skeleton
          key={index}
          variant="rounded"
          animation="wave"
          width="9%"
          height={`${height}%`}
          sx={{ ...skeletonSx, borderRadius: "6px 6px 2px 2px" }}
        />
      ))}
    </Box>
  </Box>
);

export function MapPageSkeletonContent({
  variant,
}: {
  variant: MapSkeletonVariant;
}) {
  if (variant === "network-simulation") {
    return <DeviceListSkeleton cleaning={false} />;
  }

  if (variant === "scada-data-cleaning") {
    return <DeviceListSkeleton cleaning />;
  }

  if (variant === "health-risk-analysis") {
    return <RiskChartSkeleton />;
  }

  return (
    <Box
      data-testid={`${variant}-content`}
      sx={{
        display: "flex",
        flexDirection: "column",
        gap: 2,
        height: "100%",
        minHeight: 0,
      }}
    >
      <AnalysisFormSkeleton variant={variant} />
    </Box>
  );
}

export function MapTimelineSkeleton() {
  return (
    <Box
      role="status"
      aria-live="polite"
      aria-label="正在加载时间轴"
      data-component-skeleton="map-timeline"
      data-testid="map-timeline-skeleton"
      sx={{
        position: "absolute",
        left: "50%",
        bottom: 16,
        width: "min(950px, calc(100% - 32px))",
        transform: "translateX(-50%)",
        display: "grid",
        gap: 1.5,
        p: 2,
        bgcolor: "rgba(255, 255, 255, 0.96)",
        borderRadius: 1.5,
        boxShadow:
          "0 14px 30px rgba(15, 23, 42, 0.16), 0 2px 6px rgba(15, 23, 42, 0.08)",
        pointerEvents: "none",
      }}
    >
      <Box sx={{ display: "flex", alignItems: "center", gap: 1.5 }}>
        {Array.from({ length: 5 }, (_, index) => (
          <Skeleton
            key={index}
            variant="circular"
            animation="wave"
            width={32}
            height={32}
            sx={skeletonSx}
          />
        ))}
        <Box sx={{ flex: 1 }} />
        <Skeleton
          variant="rounded"
          animation="wave"
          width={132}
          height={32}
          sx={{ ...skeletonSx, borderRadius: 1 }}
        />
      </Box>
      <Skeleton
        variant="rounded"
        animation="wave"
        height={8}
        sx={{ ...skeletonSx, borderRadius: 999 }}
      />
    </Box>
  );
}
