import { CChart } from "@coreui/react-chartjs";
import { Col, Row, Form } from "react-bootstrap";
import { getPorts, getSpotRageAvg } from "@/services/public";
import React, { useEffect, useState } from "react";
import DatePicker from "react-datepicker";
import Moment from "moment";
import { signOut, useSession } from "next-auth/react";
import "react-datepicker/dist/react-datepicker.css";
import { useRouter } from "next/router";
import { toast } from "react-toastify";
import { ScaleLoader } from "react-spinners";
import ProtectedRoute from "@/publicRoute";

interface PortType {
  id: number | string | null;
  name: string | null;
  state_code: string | null;
  zip: string | null;
  mode: string | null;
  lat: string | null;
  lng: string | null;
}

type DateType = Date | null;

function SpotRateAvg() {
  const { data } = useSession();
  const Router = useRouter();

  const [portsData, setPortsData] = useState([]);
  const [selectedPort, setSelectedPort] = useState<string>("");
  const [graphLabel, setGraphLabel] = useState<string>("");
  const [graphData, setGraphData] = useState<number[]>([]);
  const [loading, setLoading] = useState<boolean>(false);

  let today = new Date();

  const [endDate, setEndDate] = useState<DateType>(null);

  const [startDate, setStartDate] = useState<DateType>(null);
  const [lables, setLables] = useState<unknown[]>([]);

  function getNewDateLessWithSixMonthsLesser() {
    let currentDate = new Date();
    // Calculate the new date by subtracting 6 months (180 days) from the current date
    currentDate.setMonth(currentDate.getMonth() - 5);

    return currentDate;
  }

  const handleDateChange = (dates: DateType[]) => {
    const [start, end] = dates;

    setStartDate(start);
    setEndDate(end);
  };

  function dateRange(start_date: Date, end_date: Date): string[] {
    var result = [];
    let startMon = Moment(start_date);
    let endMon = Moment(end_date).add(1, "month");

    if (endMon.isBefore(startMon)) {
      alert("End date must be greated than start date.");
    }

    if (endMon.diff(startMon, "year") >= 1) {
      while (startMon.isBefore(endMon)) {
        result.push(startMon.format("MMMM-yy"));
        startMon.add(1, "month");
      }
    } else {
      while (startMon.isBefore(endMon)) {
        result.push(startMon.format("MMMM"));
        startMon.add(1, "month");
      }
    }
    return result;
  }

  function makeGraphData(respData: any[], start_date: Date, end_date: Date) {
    let startMon = Moment(start_date);
    let endMon = Moment(end_date).add(1, "month");
    let numArr: number[] = [];

    while (startMon.isBefore(endMon)) {
      let existingObj = respData?.filter((elem) => {
        let resDate = Moment(
          new Date(`${elem?.created_year}-${elem?.created_month}`),
        );

        if (
          (resDate.diff(startMon, "months", true) < 0 &&
            resDate.diff(startMon, "months", true) > -1) ||
          resDate.diff(startMon, "months", true) == 0
        ) {
          return elem;
        }
      });

      if (existingObj.length > 0) {
        numArr.push(existingObj[0].spot_rate_avg);
      } else {
        numArr.push(0);
      }
      startMon.add(1, "month");
    }

    setGraphData(numArr);
    setLables(dateRange(start_date, end_date));
  }

  function makeApiCall(queryString: string, start_Date: Date, end_Date: Date) {
    setLoading(true);
    getSpotRageAvg(data?.user?.image, queryString)
      .then((resp) => {
        setLoading(false);

        if (resp?.status == "success") {
          makeGraphData(resp.data, start_Date, end_Date);
        }
      })
      .catch((err) => {
        setLoading(false);
        toast.error(err.message, {
          position: toast.POSITION.TOP_CENTER,
        });
      });
  }

  useEffect(() => {
    if (selectedPort.length > 0) {
      if (!data?.user?.image) {
        toast.error("Token Expired, Please Login again.", {
          position: toast.POSITION.TOP_CENTER,
        });
        signOut({ redirect: false }).then(() => {
          Router.push("/login");
        });

        return;
      }
      makeApiCall(
        `port_id=${selectedPort}`,
        getNewDateLessWithSixMonthsLesser(),
        today,
      );

      const filteredPort: PortType = portsData?.filter(
        (e: PortType) => e.id == selectedPort,
      )[0];
      setGraphLabel(`${filteredPort?.state_code}-${filteredPort?.name}`);
    } else {
      setEndDate(null);
      setStartDate(null);
    }
  }, [selectedPort]);

  useEffect(() => {
    if (startDate && endDate && selectedPort?.length > 0) {
      let start_date = Moment(startDate).format("YYYY-MM");
      let end_date = Moment(endDate).format("YYYY-MM");
      makeApiCall(
        `port_id=${selectedPort}&start_date=${start_date}&end_date=${end_date}`,
        startDate,
        endDate,
      );
    }
  }, [endDate, startDate, selectedPort]);

  useEffect(() => {
    getPorts().then((response) => {
      if (response.status == "success") {
        setPortsData(response.data);
      }
    });
  }, []);

  const handleReset = () => {
    setSelectedPort("");
    setStartDate(null);
    setEndDate(null);
  };

  return (
    <div className="chart_block">
      <div className="port_ramp_tow">
        <h3>Spot Rate Avg. By Market</h3>
      </div>
      <Row>
        <Col xs={6} className="pe-1">
          <div className="form_body">
            <Form.Label className="form-label" htmlFor="port_ramp">
              Market
            </Form.Label>
            <Form.Select
              className={`form-select-sm pe-1 `}
              id="port_ramp"
              value={selectedPort}
              onChange={(e: any) => setSelectedPort(e.target.value)}
            >
              <option value={""}>Select Market</option>
              {portsData?.map((item: any) => {
                return (
                  <option key={item.id} value={item.id}>
                    {item.state_code}-{item.name}
                  </option>
                );
              })}
            </Form.Select>
          </div>
        </Col>
        <Col xs={6} className="ps-1">
          <div className="form_body">
            <Form.Label className="form-label">Select Date Range</Form.Label>
            <div className="">
              <DatePicker
                className="form-select form-select-sm pe-0 py-1 fs-14"
                selected={startDate}
                onChange={handleDateChange}
                startDate={startDate}
                endDate={endDate}
                selectsRange
                showMonthYearPicker
                dateFormat="MM/yyyy"
                disabled={selectedPort.length === 0}
                maxDate={Moment().toDate()}
              />
            </div>
          </div>
        </Col>
      </Row>
      <Row className="mt-1">
        <Col xs={6}></Col>
        <Col xs={6} className="text-end clear_all_text_card">
          <button
            className="border-bottom fs-12 pe-auto text-danger text-uppercase"
            style={{ all: "unset" }}
            onClick={handleReset}
          >
            Clear All
          </button>
        </Col>
      </Row>

      <div className="pic mt-4">
        {selectedPort.length > 0 &&
          (loading ? (
            <div className="text-center">
              <ScaleLoader color="#3180f3" />
            </div>
          ) : (
            <CChart
              type="line"
              data={{
                labels: lables,
                datasets: [
                  {
                    label: graphLabel,
                    backgroundColor: "rgba(49, 128, 243, 0.5)",
                    borderColor: "rgba(220, 220, 220, 1)",
                    pointBackgroundColor: "rgba(220, 220, 220, 1)",
                    pointBorderColor: "#3F25D9",
                    data: graphData,
                    fill: true,
                  },
                ],
              }}
              options={{
                scales: {
                  y: {
                    beginAtZero: true,
                    ticks: {
                      callback: function (value) {
                        return "$" + value.toFixed(2);
                      },
                    },
                  },
                },
                plugins: {
                  tooltip: {
                    enabled: true,
                    callbacks: {
                      label: function (context) {
                        const label = context.dataset.label || "";
                        let value = context.parsed.y;
                        value = "$" + value.toFixed(2);
                        return label + ": " + value;
                      },
                    },
                  },
                },
              }}
            />
          ))}
        {selectedPort.length === 0 && (
          <h6 className="text-center mt-4 fs-14">Please Select Market </h6>
        )}
      </div>
    </div>
  );
}

export default ProtectedRoute(SpotRateAvg);
