// @ts-nocheck
/* eslint-disable */

import type { NextApiRequest, NextApiResponse } from "next";
import type { AssetPriceData, Tick } from "~/interfaces/simulator";

const brapiBaseUrl = "https://brapi.dev/api";

async function fetchPriceData(ticker: string): Promise<null | Tick[]> {
  try {
    const url = `${brapiBaseUrl}/quote/${ticker}?range=10y&interval=1d&fundamental=false`;
    const data = await fetch(url).then((res) => res.json());
    if (
      !data ||
      !data.results ||
      !data.results[0] ||
      !data.results[0].historicalDataPrice ||
      data.results[0].historicalDataPrice.length < 2
    ) {
      throw new Error(
        `No historical price data found for asset with ID ${ticker}`
      );
    }
    return data.results[0].historicalDataPrice;
  } catch (error) {
    console.error(error);
    return null;
  }
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const ticker: string | string[] | undefined = req.query.ticker;
  if (ticker !== undefined) {
    const data = await fetchPriceData(ticker as string);
    if (data !== null) {
      let tempPriceData: { [key: number]: Tick } = {};
      try {
        let priceDataCorrectTs: Tick[] = [];
        for (const tick of data) {
          const thisDateYMD: string[] = new Date(tick.date * 1000)
            .toISOString()
            .split("T")[0]!
            .split("-");

          const thisDate = Date.UTC(
            parseInt(thisDateYMD[0]!),
            // month index, 0 is jan, 11 is dec
            parseInt(thisDateYMD[1]!) - 1,
            parseInt(thisDateYMD[2]!)
          );
          priceDataCorrectTs.push({
            ...tick,
            date: thisDate,
          });
        }

        for (let i = 0; i < priceDataCorrectTs.length; i++) {
          const thisTick = priceDataCorrectTs[i];
          if (thisTick) {
            const currentTs = thisTick.date;
            const currentTsInSeconds = currentTs / 1000;

            if (thisTick.close === null) {
              // look backwards for a substitute
              for (let k = i; k >= 0; k--) {
                const replacementTick = priceDataCorrectTs[k];
                if (replacementTick && replacementTick.close !== null) {
                  tempPriceData[currentTsInSeconds] = {
                    ...replacementTick,
                    date: currentTsInSeconds,
                  };
                  break;
                }
              }
            } else {
              tempPriceData[currentTsInSeconds] = {
                ...thisTick,
                date: currentTsInSeconds,
              };
              const nextTick = priceDataCorrectTs[i + 1];
              if (nextTick) {
                const nextTs = nextTick.date;

                if (nextTs - currentTs > 86400000) {
                  const days = Math.floor((nextTs - currentTs) / 86400000) - 1;
                  const nextDate = new Date(currentTs);
                  for (let j = 1; j <= days; j++) {
                    nextDate.setUTCDate(nextDate.getUTCDate() + 1);
                    const tsInSeconds = nextDate.getTime() / 1000;
                    tempPriceData[tsInSeconds] = {
                      ...thisTick,
                      date: tsInSeconds,
                    };
                  }
                }
              }
            }
          }
        }
      } catch (e) {
        console.error(e);
      }

      const transformedPriceData: Tick[] = Object.values(tempPriceData);
      const hasData = transformedPriceData.length > 0 ? true : false;

      if (!hasData) return null;

      const result: AssetPriceData = {
        ticker: ticker as string,
        data: transformedPriceData,
      };

      res.status(200).json(result);
    } else {
      res.status(404).json({ ticker: null, data: null });
    }
  }
}
