import * as React from "react";
import {
  Box,
  Typography,
  ToggleButtonGroup,
  ToggleButton,
  Paper
} from "@mui/material";
import { useTheme, alpha } from "@mui/material/styles";
import IconButton from "@mui/material/IconButton";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import {
  ChartDataPoint,
  HistoryChartProps,
} from "./HistoryChart.models";
import { formatDisplay } from "./HistoryChart.utils";

interface ViewProps extends HistoryChartProps {
  activeTab: string;
  setActiveTab: (v: string) => void;
  currentData: ChartDataPoint[];
  visibleData: ChartDataPoint[];
  maxAmount: number;
  visibleCount: number;
  startIndex: number;
  setStartIndex: React.Dispatch<React.SetStateAction<number>>;
  activeDataKey: string;
}

export default function HistoryChartView(props: ViewProps) {
  const {
    header,
    summary,
    tabs,
    colorScheme,

    mode,
    periodType,
    selectedPeriodId,
    comparison,

    togglePeriodType,
    setSelectedPeriodId,
    toggleComparison,

    activeTab,
    setActiveTab,
    currentData,
    visibleData,
    maxAmount,
    visibleCount,
    startIndex,
    setStartIndex,
    activeDataKey,
  } = props;

  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  const handleTabChange = (_: React.MouseEvent<HTMLElement>, newTab: string | null) => {
    if (newTab !== null) setActiveTab(newTab);
  };

  const canGoLeft = startIndex > 0;
  const canGoRight = startIndex + visibleCount < currentData.length;

  const handlePrev = () => {
    if (canGoLeft) setStartIndex((prev) => prev - visibleCount);
  };

  const handleNext = () => {
    if (canGoRight) setStartIndex((prev) => prev + visibleCount);
  };

  return (
    <Paper
      sx={{
        p: { xs: 2.5, sm: 4 },
        borderRadius: 4,
        width: "100%",
        boxShadow: "none",
        border: "1px solid",
        borderColor: "divider",
        bgcolor: isDark ? "background.paper" : colorScheme.light,
      }}
    >
      <Typography variant="h6" fontWeight={700} gutterBottom>
        {header}
      </Typography>

      {summary && (
        <Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
          {summary}
        </Typography>
      )}

      <ToggleButtonGroup value={activeTab} exclusive onChange={handleTabChange} fullWidth sx={{ mb: 4 }}>
        {tabs.map((tab) => (
          <ToggleButton key={tab} value={tab}>
            {tab}
          </ToggleButton>
        ))}
      </ToggleButtonGroup>

      <Box sx={{ display: "flex", justifyContent: "space-between", mb: 3 }}>
        <ToggleButtonGroup value={periodType} exclusive onChange={togglePeriodType} size="small">
          <ToggleButton value="rolling">Rolling</ToggleButton>
          <ToggleButton value="calendar">Calendar</ToggleButton>
        </ToggleButtonGroup>

        <ToggleButton
          value="compare"
          selected={comparison}
          onChange={toggleComparison}
          size="small"
        >
          Compare
        </ToggleButton>
      </Box>

      {currentData.length > 0 ? (
        <Box sx={{ position: "relative", mt: 4 }}>
          {canGoLeft && (
            <IconButton onClick={handlePrev} size="small" sx={{ position: "absolute", left: 0, top: "50%" }}>
              <ChevronLeftIcon fontSize="small" />
            </IconButton>
          )}

          <Box sx={{ display: "flex", alignItems: "flex-end", height: 220, mt: 4 }}>
            {visibleData.map((point) => {
              const currentHeight = (point.amount / maxAmount) * 100;
              const compareHeight = comparison
                ? ((point.compare?.amount ?? 0) / maxAmount) * 100
                : 0;

              const isSelected = selectedPeriodId === point.id;
              const display = formatDisplay(point, activeDataKey, comparison);

              return (
                <Box
                  key={point.id}
                  onClick={() =>
                    setSelectedPeriodId(isSelected ? null : point.id)
                  }
                  sx={{
                    flex: 1,
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    cursor: "pointer",
                    height: "100%"
                  }}
                >
                  <Box sx={{ display: "flex", alignItems: "flex-end", gap: 1, height: "100%" }}>
                    {comparison && (
                      <Box
                        sx={{
                          width: 8,
                          height: `${compareHeight}%`,
                          bgcolor: alpha(colorScheme.primary, 0.4),
                          borderRadius: "4px 4px 0 0"
                        }}
                      />
                    )}

                    <Box
                      sx={{
                        width: 12,
                        height: `${currentHeight}%`,
                        bgcolor: isSelected ? "warning.main" : colorScheme.primary,
                        borderRadius: "4px 4px 0 0"
                      }}
                    />
                  </Box>

                  <Typography variant="caption">
                    {point.label}
                  </Typography>

                  {comparison && point.compare && (
                    <Typography variant="caption" color="text.secondary">
                      {point.compare.label}
                    </Typography>
                  )}

                  <Typography variant="caption">
                    {display}
                  </Typography>
                </Box>
              );
            })}
          </Box>

          {canGoRight && (
            <IconButton onClick={handleNext} size="small" sx={{ position: "absolute", right: 0, top: "50%" }}>
              <ChevronRightIcon fontSize="small" />
            </IconButton>
          )}
        </Box>
      ) : (
        <Box sx={{ height: 200, display: "flex", alignItems: "center", justifyContent: "center" }}>
          <Typography color="text.secondary">No Data Available</Typography>
        </Box>
      )}
    </Paper>
  );
}
