"use client";
import * as React from "react";
import Grid from "@mui/material/Grid";
import { Card, CardHeader } from "@mui/material";
import ReactApexChart from "react-apexcharts";
import { ApexOptions } from "apexcharts";
import "../../app/global.css";
import { Input, Label } from "reactstrap";
import Select, { components } from "react-select";
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 isBetweenPlugin from "dayjs/plugin/isBetween";
import { PickersDay, PickersDayProps } from "@mui/x-date-pickers/PickersDay";
import { styled } from "@mui/material/styles";

dayjs.extend(isBetweenPlugin);
interface CustomPickerDayProps extends PickersDayProps<Dayjs> {
  isSelected: boolean;
  isHovered: boolean;
}

// Style Day
const CustomPickersDay = styled(PickersDay, {
  shouldForwardProp: (prop) => prop !== "isSelected" && prop !== "isHovered",
})<CustomPickerDayProps>(({ theme, isSelected, isHovered, day }) => ({
  borderRadius: 0,
  ...(isSelected && {
    backgroundColor: theme.palette.primary.main,
    color: theme.palette.primary.contrastText,
    "&:hover, &:focus": {
      backgroundColor: theme.palette.primary.main,
    },
  }),
  ...(isHovered && {
    backgroundColor: theme.palette.primary[theme.palette.mode],
    "&:hover, &:focus": {
      backgroundColor: theme.palette.primary[theme.palette.mode],
    },
  }),
  ...(day.day() === 0 && {
    borderTopLeftRadius: "50%",
    borderBottomLeftRadius: "50%",
  }),
  ...(day.day() === 6 && {
    borderTopRightRadius: "50%",
    borderBottomRightRadius: "50%",
  }),
})) as React.ComponentType<CustomPickerDayProps>;

const isInSameWeek = (dayA: Dayjs, dayB: Dayjs | null | undefined) => {
  if (dayB == null) {
    return false;
  }

  return dayA.isSame(dayB, "week");
};

function Day(
  props: PickersDayProps<Dayjs> & {
    selectedDay?: Dayjs | null;
    hoveredDay?: Dayjs | null;
  },
) {
  const { day, selectedDay, hoveredDay, ...other } = props;

  return (
    <CustomPickersDay
      {...other}
      day={day}
      sx={{ px: 2.5 }}
      disableMargin
      selected={false}
      isSelected={isInSameWeek(day, selectedDay)}
      isHovered={isInSameWeek(day, hoveredDay)}
    />
  );
}



// Main function
const Bspp: React.FC = () => {

  // Set Date
  const todayDate = new Date();
  const firstDayOfWeek = new Date();
  const lastDayOfWeek = new Date();
  firstDayOfWeek.setDate(todayDate.getDate() - todayDate.getDay() + 1);
  lastDayOfWeek.setDate(todayDate.getDate() - todayDate.getDay() + 7);
  const [teamTotalManhoursSpentSelect, setTeamTotalManhoursSpentSelect]: any =
    React.useState("Weekly");
  const weekDates: any[] = [];
  const monthDates: any[] = [];
  const currentDate = dayjs();
  const sixMonthsAgo = currentDate.subtract(6, "month");
  for (let i = 0; i < 7; i++) {
    const currentDate = new Date(firstDayOfWeek);
    currentDate.setDate(firstDayOfWeek.getDate() + i);
    const formattedDate = dayjs(currentDate).format("DD MMM (ddd)");
    weekDates.push(formattedDate);
  }
  for (
    let date = sixMonthsAgo.clone();
    date.isBefore(currentDate, "month");
    date = date.add(1, "month")
  ) {
    monthDates.push(date.format("MM-YYYY"));
  }
  monthDates.push(currentDate.format("MM-YYYY"));
  const [teamTotalManhoursSpentPeriod, setTeamTotalManhoursSpentPeriod]: any[] =
    React.useState(weekDates);

  // Set fake Data
  const [
    teamTotalManhoursSpentPlanData,
    setTeamTotalManhoursSpentPlanData,
  ]: any[] = React.useState([42, 42, 42, 42, 42, 0, 0]);
  const [
    teamTotalManhoursSpentActualData,
    setTeamTotalManhoursSpentActualData,
  ]: any[] = React.useState([45, 42, 60, 42, 58, 0, 0]);
  const [hoveredDay, setHoveredDay] = React.useState<Dayjs | null>(null);
  const [value, setValue] = React.useState<Dayjs | null>(dayjs());
  const [totalManHoursMonthlyFromValue, setTotalManHoursMonthlyFromValue] =
    React.useState<Dayjs>(dayjs(new Date()).subtract(6, "month"));
  const [totalManHoursMonthlyToValue, setTotalManHoursMonthlyToValue] =
    React.useState<Dayjs>(dayjs());
  const [totalManHoursMaxValue, setTotalManHoursMaxValue] = React.useState(75);

  const teamOptions = [
    { value: 1, label: "XXX Team" },
    { value: 2, label: "YYY Team" },
    { value: 3, label: "ZZZ Team" },
  ];

  // https://poe.com/
  // https://apexcharts.com/docs/chart-types/line-chart/
  // chart options
  const options: ApexOptions = {
    chart: {
      height: 350,
      type: "line",
    },
    stroke: {
      width: [2, 2],
    },
    plotOptions: {
      bar: {
        horizontal: false,
        distributed: false,
      },
    },
    dataLabels: {
      enabled: true,
    },
    xaxis: {
      categories: teamTotalManhoursSpentPeriod,
    },
    yaxis: [
      {
        title: {
          text: "Team Total Manhours Spent (Hour)",
        },
        min: 0,
        max: totalManHoursMaxValue,
        tickAmount: 5,
      },
    ],
    grid: {
      borderColor: "#f1f1f1",
    },
    annotations: {},
    series: [
      {
        name: "Planned",
        type: "line",
        color: "#efbe7d",
        data: teamTotalManhoursSpentPlanData,
      },
      {
        name: "Actual",
        type: "line",
        color: "#7cd3f2",
        data: teamTotalManhoursSpentActualData,
      },
    ],
  };

  // On click function
  const teamTotalManhoursSpentOnClick = (r: any) => {
    setTeamTotalManhoursSpentSelect(r);
    if (r === "Weekly") {
      setValue(dayjs(new Date()));
      setTeamTotalManhoursSpentPeriod(weekDates);
      setTeamTotalManhoursSpentPlanData([42, 42, 42, 42, 42, 0, 0]);
      setTeamTotalManhoursSpentActualData([45, 42, 60, 42, 58, 0, 0]);
      setTotalManHoursMaxValue(75);
    } else if (r === "Monthly") {
      setTeamTotalManhoursSpentPeriod(monthDates);
      setTeamTotalManhoursSpentPlanData([840, 840, 840, 840, 840, 840]);
      setTeamTotalManhoursSpentActualData([900, 840, 1200, 840, 1160, 840]);
      setTotalManHoursMaxValue(1250);
    }
  };

  const selectWeeklyPeriod = (r: any) => {
    const selectDate = new Date(r);
    const firstDayOfWeek = new Date();
    firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0);
    const weekDates: any[] = [];
    for (let i = 0; i < 7; i++) {
      const currentDate = new Date(firstDayOfWeek);
      currentDate.setDate(firstDayOfWeek.getDate() + i);
      const formattedDate = dayjs(currentDate).format("DD MMM (ddd)");
      weekDates.push(formattedDate);
    }
    setTeamTotalManhoursSpentPeriod(weekDates);
    setValue(dayjs(firstDayOfWeek));
  };

  const selectMonthlyPeriodFrom = (r: any) => {
    const monthDates: any[] = [];
    const monthPlanData: any[] = [];
    const monthActualData: any[] = [];
    const selectFromDate = dayjs(r);
    for (
      let date = selectFromDate.clone();
      date.isBefore(totalManHoursMonthlyToValue, "month");
      date = date.add(1, "month")
    ) {
      monthDates.push(date.format("MM-YYYY"));
      monthPlanData.push(840);
      monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
    }
    monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY"));
    monthPlanData.push(840);
    monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
    setTeamTotalManhoursSpentPlanData(monthPlanData);
    setTeamTotalManhoursSpentActualData(monthActualData);
    setTeamTotalManhoursSpentPeriod(monthDates);
  };

  const selectMonthlyPeriodTo = (r: any) => {
    const monthDates: any[] = [];
    const monthPlanData: any[] = [];
    const monthActualData: any[] = [];
    const selectToDate = dayjs(r);
    for (
      let date = totalManHoursMonthlyFromValue.clone();
      date.isBefore(selectToDate, "month");
      date = date.add(1, "month")
    ) {
      monthDates.push(date.format("MM-YYYY"));
      monthPlanData.push(840);
      monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
    }
    monthDates.push(selectToDate.format("MM-YYYY"));
    monthPlanData.push(840);
    monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
    setTeamTotalManhoursSpentPlanData(monthPlanData);
    setTeamTotalManhoursSpentActualData(monthActualData);
    setTeamTotalManhoursSpentPeriod(monthDates);
  };

  // render
  return (
    <>
      <Grid item sm>
        <div style={{ display: "inline-block", width: "40%" }}>
          <div>
            <Grid item xs={12} md={12} lg={12}>
              <Card>
                <CardHeader
                  className="text-slate-500"
                  title="Team Total Manhours Spent"
                />
                <div style={{ display: "inline-block", width: "99%" }}>
                  {/* Weekly / Monthly Button select */}
                  {/* Different: selected style & on click function */}
                  <div className="w-fit align-top mr-5 float-right">
                    {teamTotalManhoursSpentSelect === "Weekly" && (
                      <>
                        <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid rounded-l-md w-32">
                          Weekly
                        </button>
                        <button
                          onClick={() =>
                            teamTotalManhoursSpentOnClick("Monthly")
                          }
                          className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-r-md w-32"
                        >
                          Monthly
                        </button>
                      </>
                    )}
                    {teamTotalManhoursSpentSelect === "Monthly" && (
                      <>
                        <button
                          onClick={() =>
                            teamTotalManhoursSpentOnClick("Weekly")
                          }
                          className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-l-md w-32"
                        >
                          Weekly
                        </button>
                        <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid rounded-r-md w-32">
                          Monthly
                        </button>
                      </>
                    )}
                  </div>

                  {/* Team combo */}
                  <div className="inline-block w-fit mt-2">

                    {/* Label */}
                    <div className="inline-block ml-6">
                      <Label className="text-slate-500 font-medium">
                        Team:&nbsp;
                      </Label>
                    </div>

                    {/* Select Option */}
                    <div className="inline-block ml-1 w-60">
                      <Select
                        placeholder="All Team"
                        options={teamOptions}
                        isClearable={true}
                      />
                    </div>

                    {/* Weekly / Monthly Period */}
                    <div className="ml-6 mt-2" style={{ verticalAlign: "top" }}>
                      {teamTotalManhoursSpentSelect === "Weekly" && (
                        <LocalizationProvider dateAdapter={AdapterDayjs}>
                          <DatePicker
                            className="w-72 h-10 align-top"
                            label="Period:"
                            value={value}
                            format="DD-MM-YYYY"
                            onChange={(newValue) =>
                              selectWeeklyPeriod(newValue)
                            }
                            showDaysOutsideCurrentMonth
                            displayWeekNumber
                            slots={{ day: Day }}
                            slotProps={{
                              day: (ownerState) =>
                                ({
                                  selectedDay: value,
                                  hoveredDay,
                                  onPointerEnter: () =>
                                    setHoveredDay(ownerState.day),
                                  onPointerLeave: () => setHoveredDay(null),
                                }) as any,
                            }}
                          />
                        </LocalizationProvider>
                      )}
                      {teamTotalManhoursSpentSelect === "Monthly" && (
                        <LocalizationProvider dateAdapter={AdapterDayjs}>
                          <DatePicker
                            className="w-40 h-10 align-top"
                            onChange={(newValue) =>
                              selectMonthlyPeriodFrom(newValue)
                            }
                            defaultValue={totalManHoursMonthlyFromValue}
                            label={"Form"}
                            views={["month", "year"]}
                          />
                          <DatePicker
                            className="w-40 h-10 align-top"
                            onChange={(newValue) =>
                              selectMonthlyPeriodTo(newValue)
                            }
                            defaultValue={totalManHoursMonthlyToValue}
                            label={"To"}
                            views={["month", "year"]}
                          />
                        </LocalizationProvider>
                      )}
                    </div>
                  </div>

                  {/* Render Apex Chart */}
                  <ReactApexChart
                    options={options}
                    series={options.series}
                    type="line"
                    height="400"
                  />
                </div>
              </Card>
            </Grid>
          </div>
        </div>
      </Grid>
    </>
  );
};

export default Bspp;
