import { useEffect } from "preact/hooks";
import { trpc } from "../trpc.js";
import {
  Chart as ChartJS,
  LinearScale,
  CategoryScale,
  PointElement,
  Tooltip,
  Title,
} from "chart.js";
import { Scatter } from "react-chartjs-2";
import {
  Container,
  Grid,
  Typography,
  Paper,
  Popper,
  ClickAwayListener,
} from "@mui/material";
import {
  availableUnderlyings,
  calendarExitPriceChartData,
  isPopperOpen,
  lookbackPeriodEnd,
  lookbackPeriodStart,
  maxChartPrice,
  maxN,
  popperAnchorEl,
  popperContent,
  similarCalendarPriceChartData,
  stockPriceChartData,
  underlying,
} from "./HistoricalCalendarPrices/state.js";
import { EditableStrike } from "./HistoricalCalendarPrices/EditableStrike.js";
import {
  refreshcalendarExitPriceChartData,
  refreshSimilarCalendarPriceChartData,
  refreshStockPriceChartData,
} from "./HistoricalCalendarPrices/actions.js";
import { EditableUnderlying } from "./HistoricalCalendarPrices/EditableUnderlying.js";
import { EditableDaysToFrontExpiration } from "./HistoricalCalendarPrices/EditableDaysToFrontExpiration.js";
import { EditableExitToFrontExpiration } from "./HistoricalCalendarPrices/EditableExitToFrontExpiration.js";
import { EditableDaysBetweenFrontAndBackExpiration } from "./HistoricalCalendarPrices/EditableDaysBetweenFrontAndBackExpiration.js";
import { EditableLookbackPeriodStart } from "./HistoricalCalendarPrices/EditableLookbackPeriodStart.js";
import { EditableLookbackPeriodEnd } from "./HistoricalCalendarPrices/EditableLookbackPeriodEnd.js";

ChartJS.register(LinearScale, CategoryScale, PointElement, Tooltip, Title);

const handleInit = () => {
  trpc.CalendarCharacteristicsForm.getAvailableUnderlyings
    .query()
    .then((availableUnderlyingsResponse) => {
      availableUnderlyings.value = availableUnderlyingsResponse;
      underlying.value = availableUnderlyingsResponse[0];
      refreshStockPriceChartData();
      refreshSimilarCalendarPriceChartData();
      refreshcalendarExitPriceChartData();
    });
};

export function HistoricalCalendarPrices() {
  useEffect(handleInit, []);

  return (
    <Container maxWidth="lg">
      <Grid container spacing={4}>
        <Grid item xs={12}>
          <Typography variant="h4" gutterBottom>
            <EditableUnderlying /> :
            <EditableDaysBetweenFrontAndBackExpiration />
            -Day Calendar @ <EditableStrike />
            %-from-the-money
          </Typography>
          <Typography variant="h5" gutterBottom sx={{ pl: 1 }}>
            Opening at <EditableDaysToFrontExpiration /> DTE, Closing at{" "}
            <EditableExitToFrontExpiration />
            DTE
          </Typography>
          <Typography variant="h5" gutterBottom>
            <EditableLookbackPeriodStart />-
            <EditableLookbackPeriodEnd />
          </Typography>
          <ClickAwayListener
            onClickAway={() => {
              isPopperOpen.value = false;
              // refreshSimilarCalendarPriceChartData();
              console.log("clicked away");
            }}
          >
            <Popper open={isPopperOpen.value} anchorEl={popperAnchorEl.value}>
              <Paper elevation={3} sx={{ p: 3 }}>
                {popperContent.value}
              </Paper>
            </Popper>
          </ClickAwayListener>
        </Grid>
        <Grid item xs={12}>
          <Paper elevation={3} sx={{ p: 3, minHeight: "28em", height: "100%" }}>
            {underlying.value !== null &&
            stockPriceChartData.value.length > 0 ? (
              <Scatter
                data={{
                  datasets: [
                    {
                      label: "Stock Open Price",
                      data: stockPriceChartData.value,
                    },
                  ],
                }}
                options={{
                  scales: {
                    x: {
                      title: {
                        display: true,
                        text: "Time",
                      },
                      ticks: {
                        callback: (value, index, ticks) =>
                          new Date((value as number) * 1000)
                            .toISOString()
                            .substring(0, 10),
                      },
                      min: new Date(lookbackPeriodStart.value).getTime() / 1000,
                      max: new Date(lookbackPeriodEnd.value).getTime() / 1000,
                    },
                    y: {
                      beginAtZero: false,
                      ticks: {
                        callback: (value, index, ticks) =>
                          `$${value.toString()}`,
                      },
                    },
                  },
                  elements: {
                    point: {
                      radius: 1,
                      borderWidth: 0,
                    },
                  },
                  plugins: {
                    tooltip: {
                      enabled: false,
                    },
                    legend: {
                      display: false,
                    },
                    title: {
                      display: true,
                      text: "Stock Price",
                    },
                  },
                  animation: false,
                  maintainAspectRatio: false,
                  events: [],
                }}
              />
            ) : (
              <Typography>Loading Chart...</Typography>
            )}
          </Paper>
        </Grid>
        <Grid item xs={12} md={6}>
          <Paper elevation={3} sx={{ p: 3, minHeight: "28em" }}>
            {underlying.value !== null &&
            similarCalendarPriceChartData.value.length > 0 ? (
              <Scatter
                data={{
                  datasets: [
                    {
                      label: "Calendar Open Price",
                      data: similarCalendarPriceChartData.value,
                    },
                  ],
                }}
                options={{
                  scales: {
                    x: {
                      title: {
                        display: true,
                        text: "Time",
                      },
                      ticks: {
                        callback: (value, index, ticks) =>
                          new Date((value as number) * 1000)
                            .toISOString()
                            .substring(0, 10),
                      },
                      min: new Date(lookbackPeriodStart.value).getTime() / 1000,
                      max: new Date(lookbackPeriodEnd.value).getTime() / 1000,
                    },
                    y: {
                      beginAtZero: true,
                      ticks: {
                        callback: (value, index, ticks) =>
                          `$${value.toString()}`,
                      },
                      min: 0,
                      max: maxChartPrice.value,
                    },
                  },
                  plugins: {
                    tooltip: {
                      enabled: false,
                    },
                    legend: {
                      display: false,
                    },
                    title: {
                      display: true,
                      text: "Calendar Price (Under Like Conditions)",
                    },
                  },
                  animation: false,
                  maintainAspectRatio: false,
                  events: [],
                }}
              />
            ) : (
              <Typography>Loading Chart...</Typography>
            )}
          </Paper>
        </Grid>
        <Grid item xs={12} md={6}>
          <Paper elevation={3} sx={{ p: 3, minHeight: "28em" }}>
            {underlying.value !== null &&
            similarCalendarPriceChartData.value.length > 0 ? (
              <Scatter
                data={{
                  datasets: [
                    {
                      label: "Calendar Exit Price",
                      data: calendarExitPriceChartData.value,
                    },
                  ],
                }}
                options={{
                  scales: {
                    x: {
                      type: "linear",
                      beginAtZero: false,
                      title: {
                        display: true,
                        text: "%-From-the-Money",
                      },
                      ticks: {
                        callback: (value, index, ticks) =>
                          `${value.toString()}%`,
                      },
                    },
                    y: {
                      beginAtZero: true,
                      ticks: {
                        callback: (value, index, ticks) =>
                          `$${value.toString()}`,
                      },
                      min: 0,
                      max: maxChartPrice.value,
                    },
                  },
                  elements: {
                    point: {
                      borderWidth: 0,
                      backgroundColor: (context) => {
                        const n = (
                          context.raw as { x: number; y: number; n: number }
                        ).n;
                        const alpha = n / maxN.value;
                        return `rgba(0, 0, 0, ${alpha})`;
                      },
                    },
                  },
                  plugins: {
                    tooltip: {
                      enabled: false,
                    },
                    legend: {
                      display: false,
                    },
                    title: {
                      display: true,
                      text: [
                        "Calendar Prices at Exit",
                        "by %-age from-the-money",
                      ],
                    },
                  },
                  animation: false,
                  maintainAspectRatio: false,
                  events: [],
                }}
              />
            ) : (
              <Typography>Loading Chart...</Typography>
            )}
          </Paper>
        </Grid>
      </Grid>
    </Container>
  );
}
