<script lang="ts">
  import { analystEstimateComponent, stockTicker } from "$lib/store";
  import { abbreviateNumber, computeGrowthSingleList } from "$lib/utils";
  import EstimationGraph from "$lib/components/EstimationGraph.svelte";
  import Lazy from "svelte-lazy";

  export let data;

  let analystEstimateList = [];
  let isLoaded = false;

  let xData = [];
  let optionsRevenue = null;
  let optionsEPS = null;
  let optionsNetIncome = null;
  let optionsEbitda = null;

  let optionsRevenueGrowth = null;
  let optionsEPSGrowth = null;
  let optionsNetIncomeGrowth = null;
  let optionsEbitdaGrowth = null;

  let revenueDateList = [];
  let avgRevenueList = [];
  let lowRevenueList = [];
  let highRevenueList = [];

  let epsDateList = [];
  let avgEPSList = [];
  let lowEPSList = [];
  let highEPSList = [];

  let netIncomeDateList = [];
  let avgNetIncomeList = [];
  let lowNetIncomeList = [];
  let highNetIncomeList = [];

  let ebitdaDateList = [];
  let avgEbitdaList = [];
  let lowEbitdaList = [];
  let highEbitdaList = [];

  let revenueAvgGrowthList = [];
  let epsAvgGrowthList = [];
  let netIncomeAvgGrowthList = [];
  let ebitdaAvgGrowthList = [];

  function fillMissingDates(dates, highGrowthList) {
    // Get the current year
    const currentYear = new Date().getFullYear();
    const currentFiscalYear = `FY${currentYear % 100}`; // Get the current fiscal year (e.g., 2024 => FY24)

    // Create a map from the highGrowthList for quick lookup
    const highGrowthMap = new Map(
      highGrowthList?.map((item) => [`FY${item.FY}`, item]),
    );

    // Generate the complete list based on the dates array
    return dates?.map((date) => {
      // Check if the date is the current fiscal year or it exists in the map
      const data = highGrowthMap?.get(date) || {
        FY: date?.slice(2),
        val: null,
        growth: null,
      };

      // If the fiscal year is the current one, set val and growth to null
      if (date === currentFiscalYear) {
        data.val = null;
        data.growth = null;
      }

      return data;
    });
  }

  function computeGrowthList(tableActualRevenue, tableForecastRevenue) {
    return tableActualRevenue?.map((item, index) => {
      const currentFY = item?.FY;

      // If it's the first item or the list is empty, return null growth
      if (index === 0 || tableActualRevenue.length === 0) {
        return { FY: currentFY, growth: null };
      }

      // If actual value is null, compute growth based on forecast values
      if (item?.val === null) {
        const prevForecastVal = tableForecastRevenue[index - 1]?.val ?? 0;
        const currentForecastVal = tableForecastRevenue[index]?.val ?? 0;

        if (prevForecastVal === 0 || currentForecastVal === 0) {
          return { FY: currentFY, growth: null };
        }

        const forecastGrowth =
          ((currentForecastVal - prevForecastVal) / Math.abs(prevForecastVal)) *
          100;

        return {
          FY: currentFY,
          growth:
            forecastGrowth !== 0 ? Number(forecastGrowth?.toFixed(2)) : null,
        };
      }

      // Compute actual growth for non-null actual values
      const prevActualVal = tableActualRevenue[index - 1]?.val ?? 0;
      const currentActualVal = item?.val ?? 0;

      if (prevActualVal === 0 || currentActualVal === 0) {
        return { FY: currentFY, growth: null };
      }

      const actualGrowth =
        ((currentActualVal - prevActualVal) / Math.abs(prevActualVal)) * 100;

      return {
        FY: currentFY,
        growth: actualGrowth !== 0 ? Number(actualGrowth.toFixed(2)) : null,
      };
    });
  }

  function findIndex(data) {
    const currentYear = new Date().getFullYear();
    // Find the index where the item's date is greater than or equal to the current year and revenue is null
    let index = data.findIndex(
      (item) => item.date >= currentYear && item?.revenue === null,
    );

    // Check if there is any item for the current year with non-null revenue
    const hasNonNullRevenue = data?.some(
      (item) => item.date === currentYear && item.revenue !== null,
    );

    // Add +1 to the index if the condition is met
    return index !== -1 && hasNonNullRevenue ? index + 1 : index;
  }

  let tableActualRevenue = [];
  let tableForecastRevenue = [];
  let tableCombinedRevenue = [];

  let tableActualEPS = [];
  let tableForecastEPS = [];
  let tableCombinedEPS = [];

  let tableActualNetIncome = [];
  let tableCombinedNetIncome = [];
  let tableForecastNetIncome = [];

  let tableActualEbitda = [];
  let tableCombinedEbitda = [];
  let tableForecastEbitda = [];

  function getPlotOptions(dataType: string) {
    let dates = [];
    let valueList = [];
    let avgList = [];
    let lowList = [];
    let highList = [];
    let filteredData =
      analystEstimateList?.filter((item) => item.date >= 2019) ?? [];
    const stopIndex = findIndex(filteredData);

    if (filteredData) {
      filteredData.forEach((item, index) => {
        const date = item.date?.toString().slice(-2);
        const isAfterStartIndex = stopIndex <= index + 1;
        dates.push(`FY${date}`);
        switch (dataType) {
          case "Revenue":
            valueList.push(isAfterStartIndex ? null : item.revenue);
            avgList.push(isAfterStartIndex ? item?.estimatedRevenueAvg : null);
            lowList.push(isAfterStartIndex ? item?.estimatedRevenueLow : null);
            highList.push(
              isAfterStartIndex ? item?.estimatedRevenueHigh : null,
            );
            break;
          case "EPS":
            valueList.push(isAfterStartIndex ? null : item.eps);
            avgList.push(isAfterStartIndex ? item.estimatedEpsAvg : null);
            lowList.push(isAfterStartIndex ? item.estimatedEpsLow : null);
            highList.push(isAfterStartIndex ? item.estimatedEpsHigh : null);
            break;
          case "NetIncome":
            valueList.push(isAfterStartIndex ? null : item.netIncome);
            avgList.push(isAfterStartIndex ? item.estimatedNetIncomeAvg : null);
            lowList.push(isAfterStartIndex ? item.estimatedNetIncomeLow : null);
            highList.push(
              isAfterStartIndex ? item.estimatedNetIncomeHigh : null,
            );
            break;
          case "Ebitda":
            valueList.push(isAfterStartIndex ? null : item.ebitda);
            avgList.push(isAfterStartIndex ? item.estimatedEbitdaAvg : null);
            lowList.push(isAfterStartIndex ? item.estimatedEbitdaLow : null);
            highList.push(isAfterStartIndex ? item.estimatedEbitdaHigh : null);
            break;
          default:
            break;
        }
      });
    }

    try {
      const lastValue = valueList[stopIndex - 2];
      avgList[stopIndex - 2] = lastValue;
      lowList[stopIndex - 2] = lastValue;
      highList[stopIndex - 2] = lastValue;
    } catch (e) {
      console.log(e);
    }

    // Normalize the data if needed (not required in this case, but leaving it here for reference)

    let currentYearSuffix = new Date().getFullYear()?.toString().slice(-2);
    let searchString = `FY${currentYearSuffix}`;
    let currentYearIndex = dates?.findIndex((date) => date === searchString);

    // Assign to global variables based on dataType
    if (dataType === "Revenue") {
      revenueDateList = dates?.slice(currentYearIndex) || [];
      avgRevenueList =
        avgList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: revenueDateList[index]?.slice(2),
          val: val,
        })) || [];
      lowRevenueList =
        lowList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: revenueDateList[index]?.slice(2),
          val: val,
        })) || [];
      highRevenueList =
        highList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: revenueDateList[index]?.slice(2),
          val: val,
        })) || [];
    } else if (dataType === "EPS") {
      epsDateList = dates?.slice(currentYearIndex) || [];
      avgEPSList =
        avgList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: epsDateList[index]?.slice(2),
          val: val,
        })) || [];
      lowEPSList =
        lowList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: epsDateList[index]?.slice(2),
          val: val,
        })) || [];
      highEPSList =
        highList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: epsDateList[index]?.slice(2),
          val: val,
        })) || [];
    } else if (dataType === "NetIncome") {
      netIncomeDateList = dates?.slice(currentYearIndex) || [];
      avgNetIncomeList =
        avgList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: netIncomeDateList[index]?.slice(2),
          val: val,
        })) || [];
      lowNetIncomeList =
        lowList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: netIncomeDateList[index]?.slice(2),
          val: val,
        })) || [];
      highNetIncomeList =
        highList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: netIncomeDateList[index]?.slice(2),
          val: val,
        })) || [];
    } else if (dataType === "Ebitda") {
      ebitdaDateList = dates?.slice(currentYearIndex) || [];
      avgEbitdaList =
        avgList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: ebitdaDateList[index]?.slice(2),
          val: val,
        })) || [];
      lowEbitdaList =
        lowList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: ebitdaDateList[index]?.slice(2),
          val: val,
        })) || [];
      highEbitdaList =
        highList?.slice(currentYearIndex)?.map((val, index) => ({
          FY: ebitdaDateList[index]?.slice(2),
          val: val,
        })) || [];
    }
    const growthList = dates?.map((date) => {
      const fy = parseInt(date.replace("FY", ""), 10); // Extract numeric FY value
      const listToUse =
        dataType === "Revenue"
          ? revenueAvgGrowthList
          : dataType === "EPS"
            ? epsAvgGrowthList
            : dataType === "NetIncome"
              ? netIncomeAvgGrowthList
              : ebitdaAvgGrowthList; // Select the correct growth list
      const growth = listToUse?.find((r) => r.FY === fy); // Find matching FY
      return growth ? growth?.growth : null; // Return growth or null if not found
    });

    const option = {
      silent: true,
      tooltip: {
        trigger: "axis",
        hideDelay: 100, // Set the delay in milliseconds
      },
      animation: false,
      grid: {
        left: "5%",
        right: "5%",
        bottom: "2%",
        top: "5%",
        containLabel: true,
      },
      xAxis: {
        type: "category",
        boundaryGap: false,
        data: dates,
        axisLabel: {
          color: "#fff",
        },
      },
      tooltip: {
        trigger: "axis",
        hideDelay: 100,
        borderColor: "#969696", // Black border color
        borderWidth: 1, // Border width of 1px
        backgroundColor: "#313131", // Optional: Set background color for contrast
        textStyle: {
          color: "#fff", // Optional: Text color for better visibility
        },
        formatter: function (params) {
          // Get the timestamp from the first parameter
          const timestamp = params[0].axisValue;

          // Sort the params array to arrange High, Avg, Low
          const sortedParams = params.sort((a, b) => {
            const order = { High: 0, Avg: 1, Low: 2 };
            return order[a.seriesName] - order[b.seriesName];
          });

          // Initialize result with timestamp
          let result = timestamp + "<br/>";

          // Loop through each sorted series data
          sortedParams.forEach((param) => {
            result +=
              param.seriesName + ": " + abbreviateNumber(param.value) + "<br/>";
          });

          return result;
        },
      },

      yAxis: [
        {
          type: "value",
          splitLine: {
            show: false, // Disable x-axis grid lines
          },

          axisLabel: {
            show: false, // Hide y-axis labels
          },
        },
      ],
      series: [
        {
          name: "Actual",
          data: valueList,
          type: "line",
          itemStyle: {
            color: "#fff", // Change line plot color to white
          },
          showSymbol: false, // Show symbols for line plot points
        },
        {
          name: "Avg",
          data: avgList,
          type: "line",
          itemStyle: {
            color: "#fff", // Change line plot color to green
          },
          lineStyle: {
            type: "dashed", // Set the line type to dashed
          },
          showSymbol: false, // Show symbols for line plot points
        },
        {
          name: "Low",
          data: lowList,
          type: "line",
          itemStyle: {
            color: "#3CB2EF", // Change line plot color to green
          },
          lineStyle: {
            type: "dashed", // Set the line type to dashed
            color: "#c2c7cf",
          },

          showSymbol: false, // Show symbols for line plot points
        },
        {
          name: "High",
          data: highList,
          type: "line",
          itemStyle: {
            color: "#3CB2EF", // Change line plot color to green
          },
          lineStyle: {
            type: "dashed", // Set the line type to dashed
            color: "#c2c7cf",
          },
          showSymbol: false, // Show symbols for line plot points
        },
      ],
    };

    let highGrowthList = [];
    let lowGrowthList = [];
    if (dataType === "Revenue") {
      highGrowthList = computeGrowthSingleList(highRevenueList, avgRevenueList);
      lowGrowthList = computeGrowthSingleList(lowRevenueList, avgRevenueList);
    } else if (dataType === "EPS") {
      highGrowthList = computeGrowthSingleList(highEPSList, avgEPSList);
      lowGrowthList = computeGrowthSingleList(lowEPSList, avgEPSList);
    } else if (dataType === "NetIncome") {
      highGrowthList = computeGrowthSingleList(
        highNetIncomeList,
        avgNetIncomeList,
      );
      lowGrowthList = computeGrowthSingleList(
        lowNetIncomeList,
        avgNetIncomeList,
      );
    } else if (dataType === "Ebitda") {
      highGrowthList = computeGrowthSingleList(highEbitdaList, avgEbitdaList);
      lowGrowthList = computeGrowthSingleList(lowEbitdaList, avgEbitdaList);
    }

    highGrowthList = fillMissingDates(dates, highGrowthList)?.map(
      (item) => item?.growth,
    );

    lowGrowthList = fillMissingDates(dates, lowGrowthList)?.map(
      (item) => item?.growth,
    );

    const optionsGrowth = {
      animation: false,
      grid: {
        left: "5%",
        right: "5%",
        bottom: "2%",
        top: "5%",
        containLabel: true,
      },
      xAxis: {
        type: "category",
        boundaryGap: false,
        data: dates,
        axisLabel: {
          color: "#fff",
        },
      },
      yAxis: [
        {
          type: "value",
          splitLine: {
            show: false, // Disable x-axis grid lines
          },
          axisLabel: {
            show: false, // Hide y-axis labels
          },
        },
      ],
      series: [
        {
          name:
            dataType === "Revenue"
              ? "Revenue Growth"
              : dataType === "EPS"
                ? "EPS Growth"
                : dataType === "NetIncome"
                  ? "Net Income Growth"
                  : "EBITDA Growth",
          data: growthList?.map((value) => ({
            value,
            itemStyle: {
              color: value >= 0 ? "#00FC50" : "#D9220E", // Green for >= 0, Red for < 0
            },
          })),
          type: "bar",
          smooth: true,
          z: 5, // Ensure the bar chart has a lower z-index than the error bars
        },
        {
          name: "Error Bars",
          type: "custom",
          renderItem: (params, api) => {
            const xValue = api.value(0);
            const yValue = api.value(1);

            // Select high and low lists based on dataType
            const highList = highGrowthList;
            const lowList = lowGrowthList;

            // Retrieve the corresponding high and low values
            const high = highList[params.dataIndex];
            const low = lowList[params.dataIndex];

            // Skip rendering error bars if high or low values are null or undefined
            if (high == null || low == null) return; // Null or undefined values are skipped

            const x = api.coord([xValue, yValue])[0];
            const highCoord = api.coord([xValue, high])[1];
            const lowCoord = api.coord([xValue, low])[1];

            return {
              type: "group",
              children: [
                {
                  type: "line",
                  shape: {
                    x1: x,
                    y1: highCoord,
                    x2: x,
                    y2: lowCoord,
                  },
                  style: {
                    stroke: "#fff",
                    lineWidth: 2, // Set thicker line width
                  },
                },
                {
                  type: "line",
                  shape: {
                    x1: x - 5,
                    y1: highCoord,
                    x2: x + 5,
                    y2: highCoord,
                  },
                  style: {
                    stroke: "#fff",
                    lineWidth: 2, // Set thicker line width
                  },
                },
                {
                  type: "line",
                  shape: {
                    x1: x - 5,
                    y1: lowCoord,
                    x2: x + 5,
                    y2: lowCoord,
                  },
                  style: {
                    stroke: "#fff",
                    lineWidth: 2, // Set thicker line width
                  },
                },
              ],
            };
          },
          encode: {
            x: 0, // Map x-axis values
            y: 1, // Map y-axis values
          },
          data: growthList?.map((value, index) => [index, value]), // Prepare data for error bars
          z: 10, // Bring the error bars to the front
        },
      ],
      tooltip: {
        trigger: "axis",
        hideDelay: 100,
        borderColor: "#969696", // Black border color
        borderWidth: 1, // Border width of 1px
        backgroundColor: "#313131", // Optional: Set background color for contrast
        textStyle: {
          color: "#fff", // Optional: Text color for better visibility
        },
        formatter: (params) => {
          const dataIndex = params[0].dataIndex;
          const mainValue = params[0].value;

          // Select high and low lists based on dataType
          const highList = highGrowthList;
          const lowList = lowGrowthList;

          // Retrieve the corresponding high and low values
          const high = highList[dataIndex];
          const low = lowList[dataIndex];

          // Only show High and Low if they are not "N/A"
          let tooltipContent = `<b>${dates[dataIndex]}</b><br>`;

          if (high && high !== "N/A") {
            tooltipContent += `High: ${high.toFixed(2)}<br>`;
          }

          if (mainValue && mainValue !== "N/A") {
            tooltipContent += `Avg: ${mainValue.toFixed(2)}<br>`;
          }

          if (low && low !== "N/A") {
            tooltipContent += `Low: ${low.toFixed(2)}<br>`;
          }

          return tooltipContent;
        },
      },
    };

    if (dataType === "Revenue") {
      optionsRevenue = option;
      optionsRevenueGrowth = optionsGrowth;
    } else if (dataType === "EPS") {
      optionsEPS = option;
      optionsEPSGrowth = optionsGrowth;
    } else if (dataType === "NetIncome") {
      optionsNetIncome = option;
      optionsNetIncomeGrowth = optionsGrowth;
    } else if (dataType === "Ebitda") {
      optionsEbitda = option;
      optionsEbitdaGrowth = optionsGrowth;
    }
  }

  //To-do: Optimize this piece of shit
  function prepareData() {
    tableActualRevenue = [];
    tableForecastRevenue = [];
    tableCombinedRevenue = [];

    tableActualEPS = [];
    tableCombinedEPS = [];
    tableForecastEPS = [];

    tableActualNetIncome = [];
    tableCombinedNetIncome = [];
    tableForecastNetIncome = [];

    tableActualEbitda = [];
    tableCombinedEbitda = [];
    tableForecastEbitda = [];

    revenueAvgGrowthList = [];
    epsAvgGrowthList = [];
    netIncomeAvgGrowthList = [];
    ebitdaAvgGrowthList = [];

    let filteredData =
      analystEstimateList?.filter((item) => item.date >= 2015) ?? [];

    xData = filteredData?.map(({ date }) => Number(String(date)?.slice(-2)));
    //============================//
    //Revenue Data
    filteredData?.forEach((item) => {
      tableActualRevenue?.push({
        FY: Number(String(item?.date)?.slice(-2)),
        val: item?.revenue,
      });
      tableForecastRevenue?.push({
        FY: Number(String(item?.date)?.slice(-2)),
        val: item?.estimatedRevenueAvg,
        numOfAnalysts: item?.numOfAnalysts,
      });
    });

    tableCombinedRevenue = tableActualRevenue?.map((item1) => {
      // Find the corresponding item in data2 based on "FY"
      const item2 = tableForecastRevenue?.find(
        (item2) => item2?.FY === item1?.FY,
      );

      // If the value in data1 is null, replace it with the value from data2
      return {
        FY: item1.FY,
        val: item1.val === null ? item2.val : item1.val,
        numOfAnalysts: item2.numOfAnalysts,
      };
    });

    //============================//
    //NetIncome Data
    filteredData?.forEach((item) => {
      tableActualNetIncome?.push({
        FY: Number(String(item?.date)?.slice(-2)),
        val: item?.netIncome,
      });
      tableForecastNetIncome?.push({
        FY: Number(String(item?.date)?.slice(-2)),
        val: item?.estimatedNetIncomeAvg,
      });
    });

    tableCombinedNetIncome = tableActualNetIncome?.map((item1) => {
      // Find the corresponding item in data2 based on "FY"
      const item2 = tableForecastNetIncome?.find(
        (item2) => item2?.FY === item1?.FY,
      );

      // If the value in data1 is null, replace it with the value from data2
      return {
        FY: item1.FY,
        val: item1.val === null ? item2.val : item1.val,
      };
    });

    //============================//
    //Ebitda Data
    filteredData?.forEach((item) => {
      tableActualEbitda?.push({
        FY: Number(String(item?.date)?.slice(-2)),
        val: item?.ebitda,
      });
      tableForecastEbitda?.push({
        FY: Number(String(item?.date)?.slice(-2)),
        val: item?.estimatedEbitdaAvg,
      });
    });

    tableCombinedEbitda = tableActualEbitda?.map((item1) => {
      // Find the corresponding item in data2 based on "FY"
      const item2 = tableForecastEbitda?.find(
        (item2) => item2?.FY === item1?.FY,
      );

      // If the value in data1 is null, replace it with the value from data2
      return {
        FY: item1.FY,
        val: item1.val === null ? item2.val : item1.val,
      };
    });

    //============================//
    //EPS Data
    filteredData?.forEach((item) => {
      tableActualEPS?.push({
        FY: Number(String(item?.date)?.slice(-2)),
        val: item?.eps,
      });
      tableForecastEPS?.push({
        FY: Number(String(item?.date)?.slice(-2)),
        val: item?.estimatedEpsAvg,
      });
    });

    tableCombinedEPS = tableActualEPS?.map((item1) => {
      // Find the corresponding item in data2 based on "FY"
      const item2 = tableForecastEPS?.find((item2) => item2?.FY === item1?.FY);

      // If the value in data1 is null, replace it with the value from data2
      return {
        FY: item1.FY,
        val: item1.val === null ? item2.val : item1.val,
      };
    });

    //Values coincide with table values for crosscheck
    revenueAvgGrowthList = computeGrowthList(
      tableActualRevenue,
      tableCombinedRevenue,
    );
    netIncomeAvgGrowthList = computeGrowthList(
      tableActualNetIncome,
      tableCombinedNetIncome,
    );

    ebitdaAvgGrowthList = computeGrowthList(
      tableActualEbitda,
      tableCombinedEbitda,
    );
    epsAvgGrowthList = computeGrowthList(tableActualEPS, tableCombinedEPS);
  }

  $: {
    if ($stockTicker && typeof window !== "undefined") {
      isLoaded = false;
      analystEstimateList = [];
      analystEstimateList = data?.getAnalystEstimate || [];
      if (analystEstimateList?.length !== 0) {
        prepareData();
        $analystEstimateComponent = true;
        getPlotOptions("Revenue");
        getPlotOptions("EPS");
        getPlotOptions("NetIncome");
        getPlotOptions("Ebitda");
      } else {
        $analystEstimateComponent = false;
      }
      isLoaded = true;
    }
  }
</script>

<section class="overflow-hidden text-white h-full pb-8 sm:pb-2">
  <main class="overflow-hidden">
    <div class="w-full m-auto">
      <div class="flex flex-row items-center"></div>

      {#if isLoaded}
        {#if analystEstimateList?.length !== 0}
          <div
            class="no-scrollbar flex justify-start items-center w-screen sm:w-full mt-6 m-auto overflow-x-scroll pr-5 sm:pr-0"
          >
            <table
              class="table table-sm table-pin-cols table-compact rounded-none sm:rounded-md w-full bg-table border border-gray-800"
            >
              <thead class="">
                <tr class="">
                  <th
                    class="bg-primary border-b border-[#000] text-white font-semibold text-sm text-start"
                    >Fiscal Year</th
                  >
                  {#each xData as item}
                    <td
                      class="z-20 bg-primary border-b border-[#000] text-white font-semibold text-sm text-end bg-default"
                      >{"FY" + item}</td
                    >
                  {/each}
                </tr>
              </thead>
              <tbody class="shadow-md">
                <tr class="bg-primary border-b-[#27272A]">
                  <th
                    class="text-white whitespace-nowrap text-sm sm:text-[1rem] text-start font-medium bg-primary border-b border-[#27272A]"
                  >
                    Revenue
                  </th>
                  {#each tableCombinedRevenue as item}
                    <td
                      class="text-white text-sm sm:text-[1rem] text-end font-medium border-b border-[#27272A] bg-default"
                    >
                      {item?.val === "0.00" ||
                      item?.val === null ||
                      item?.val === 0
                        ? "n/a"
                        : abbreviateNumber(item?.val.toFixed(2))}
                    </td>
                  {/each}
                </tr>

                <tr class="bg-primary border-b-[#27272A]">
                  <th
                    class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
                  >
                    Revenue Growth
                  </th>
                  {#each computeGrowthList(tableActualRevenue, tableCombinedRevenue) as item, index}
                    <td
                      class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
                    >
                      {#if index === 0 || item?.growth === null}
                        n/a
                      {:else if tableActualRevenue[index]?.val === null}
                        <span
                          class="text-orange-400 {item?.growth > 0
                            ? "before:content-['+']"
                            : ''}"
                        >
                          {item?.growth}%&#42;
                        </span>
                      {:else}
                        <span
                          class={item?.growth > 0
                            ? "text-[#00FC50] before:content-['+']"
                            : item?.growth < 0
                              ? "text-[#FF2F1F]"
                              : ""}
                        >
                          {item?.growth}%
                        </span>
                      {/if}
                    </td>
                  {/each}
                </tr>

                <tr class="bg-primary border-b-[#09090B]">
                  <th
                    class="text-white whitespace-nowrap text-sm sm:text-[1rem] text-start font-medium bg-primary border-b border-[#27272A]"
                  >
                    EPS
                  </th>
                  {#each tableCombinedEPS as item}
                    <td
                      class="text-white text-sm sm:text-[1rem] text-end font-medium border-b border-[#27272A] bg-default"
                    >
                      {item?.val === "0.00" ||
                      item?.val === null ||
                      item?.val === 0
                        ? "-"
                        : abbreviateNumber(item?.val.toFixed(2))}
                    </td>
                  {/each}
                </tr>

                <tr class="bg-primary border-b-[#27272A]">
                  <th
                    class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
                  >
                    EPS Growth
                  </th>
                  {#each computeGrowthList(tableActualEPS, tableCombinedEPS) as item, index}
                    <td
                      class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
                    >
                      {#if index === 0 || item?.growth === null}
                        n/a
                      {:else if tableActualRevenue[index]?.val === null}
                        <span
                          class="text-orange-400 {item?.growth > 0
                            ? "before:content-['+']"
                            : ''}"
                        >
                          {item?.growth}%&#42;
                        </span>
                      {:else}
                        <span
                          class={item?.growth > 0
                            ? "text-[#00FC50] before:content-['+']"
                            : item?.growth < 0
                              ? "text-[#FF2F1F]"
                              : ""}
                        >
                          {item?.growth}%
                        </span>
                      {/if}
                    </td>
                  {/each}
                </tr>
                <tr class="bg-primary border-b-[#27272A]">
                  <th
                    class="text-white whitespace-nowrap text-sm sm:text-[1rem] text-start font-medium bg-primary border-b border-[#27272A]"
                  >
                    Net Income
                  </th>
                  {#each tableCombinedNetIncome as item}
                    <td
                      class="text-white text-sm sm:text-[1rem] text-end font-medium border-b border-[#27272A] bg-default"
                    >
                      {item?.val === "0.00" ||
                      item?.val === null ||
                      item?.val === 0
                        ? "n/a"
                        : abbreviateNumber(item?.val.toFixed(2))}
                    </td>
                  {/each}
                </tr>

                <tr class="bg-primary border-b-[#27272A]">
                  <th
                    class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
                  >
                    Net Income Growth
                  </th>
                  {#each computeGrowthList(tableActualNetIncome, tableCombinedNetIncome) as item, index}
                    <td
                      class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
                    >
                      {#if index === 0 || item?.growth === null}
                        n/a
                      {:else if tableActualNetIncome[index]?.val === null}
                        <span
                          class="text-orange-400 {item?.growth > 0
                            ? "before:content-['+']"
                            : ''}"
                        >
                          {item?.growth}%&#42;
                        </span>
                      {:else}
                        <span
                          class={item?.growth > 0
                            ? "text-[#00FC50] before:content-['+']"
                            : item?.growth < 0
                              ? "text-[#FF2F1F]"
                              : ""}
                        >
                          {item?.growth}%
                        </span>
                      {/if}
                    </td>
                  {/each}
                </tr>

                <tr class="bg-primary border-b-[#27272A]">
                  <th
                    class="text-white whitespace-nowrap text-sm sm:text-[1rem] text-start font-medium bg-primary border-b border-[#27272A]"
                  >
                    EBITDA
                  </th>
                  {#each tableCombinedEbitda as item}
                    <td
                      class="text-white text-sm sm:text-[1rem] text-end font-medium border-b border-[#27272A] bg-default"
                    >
                      {item?.val === "0.00" ||
                      item?.val === null ||
                      item?.val === 0
                        ? "n/a"
                        : abbreviateNumber(item?.val.toFixed(2))}
                    </td>
                  {/each}
                </tr>

                <tr class="bg-primary border-b-[#27272A]">
                  <th
                    class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
                  >
                    EBITDA Growth
                  </th>
                  {#each computeGrowthList(tableActualEbitda, tableCombinedEbitda) as item, index}
                    <td
                      class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
                    >
                      {#if index === 0 || item?.growth === null}
                        n/a
                      {:else if tableActualEbitda[index]?.val === null}
                        <span
                          class="text-orange-400 {item?.growth > 0
                            ? "before:content-['+']"
                            : ''}"
                        >
                          {item?.growth}%&#42;
                        </span>
                      {:else}
                        <span
                          class={item?.growth > 0
                            ? "text-[#00FC50] before:content-['+']"
                            : item?.growth < 0
                              ? "text-[#FF2F1F]"
                              : ""}
                        >
                          {item?.growth}%
                        </span>
                      {/if}
                    </td>
                  {/each}
                </tr>

                <tr class="bg-primary border-b-[#27272A]">
                  <th
                    class="text-white whitespace-nowrap text-sm sm:text-[1rem] text-start font-medium bg-primary border-b border-[#27272A]"
                    >No. Analysts</th
                  >
                  {#each tableCombinedRevenue as item}
                    <td
                      class="text-white text-sm sm:text-[1rem] text-end font-medium border-b border-[#27272A] bg-default"
                    >
                      {#if item?.FY > 24}
                        {item?.numOfAnalysts === (null || 0)
                          ? "n/a"
                          : item?.numOfAnalysts}
                      {:else}
                        -
                      {/if}
                    </td>
                  {/each}
                </tr>
              </tbody>
            </table>
          </div>
          <div class="text-white text-sm mt-2">
            Historical EPS numbers are GAAP, while forecasted numbers may be
            non-GAAP.
          </div>
          <div class="text-orange-400 text-sm mt-2">
            &#42; This value depends on the forecast
          </div>
          <!--
            <div class="mt-5 text-gray-100 text-sm sm:text-[1rem] sm:rounded-md h-auto border border-gray-600 p-4">
              <svg class="w-5 h-5 inline-block mr-0.5 flex-shrink-0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"
                ><path fill="#fff" d="M128 24a104 104 0 1 0 104 104A104.11 104.11 0 0 0 128 24m-4 48a12 12 0 1 1-12 12a12 12 0 0 1 12-12m12 112a16 16 0 0 1-16-16v-40a8 8 0 0 1 0-16a16 16 0 0 1 16 16v40a8 8 0 0 1 0 16" /></svg
              >
              For the current Fiscal Year we use available quarterly data. Complete annual data, used to compare against analyst estimates, is only finalized after the year ends.
            </div>
            -->
        {/if}
      {:else}
        <div class="flex justify-center items-center h-80">
          <div class="relative">
            <label
              class="bg-secondary rounded-md h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
            >
              <span class="loading loading-spinner loading-md text-gray-400"
              ></span>
            </label>
          </div>
        </div>
      {/if}

      <div class="space-y-6 lg:grid lg:grid-cols-2 lg:gap-6 lg:space-y-0 mt-10">
        <Lazy fadeOption={{ delay: 100, duration: 100 }} keep={true}>
          <EstimationGraph
            userTier={data?.user?.tier}
            title="Revenue"
            options={optionsRevenue}
            tableDataList={revenueDateList}
            highDataList={highRevenueList}
            avgDataList={avgRevenueList}
            lowDataList={lowRevenueList}
          />
        </Lazy>

        <Lazy fadeOption={{ delay: 100, duration: 100 }} keep={true}>
          <EstimationGraph
            userTier={data?.user?.tier}
            title="Revenue Growth"
            options={optionsRevenueGrowth}
            tableDataList={revenueDateList}
            highDataList={highRevenueList}
            avgDataList={avgRevenueList}
            lowDataList={lowRevenueList}
            avgGrowthList={revenueAvgGrowthList}
            graphType="growth"
          />
        </Lazy>

        <Lazy fadeOption={{ delay: 100, duration: 100 }} keep={true}>
          <EstimationGraph
            userTier={data?.user?.tier}
            title="EPS"
            options={optionsEPS}
            tableDataList={epsDateList}
            highDataList={highEPSList}
            avgDataList={avgEPSList}
            lowDataList={lowEPSList}
          />
        </Lazy>

        <Lazy fadeOption={{ delay: 100, duration: 100 }} keep={true}>
          <EstimationGraph
            userTier={data?.user?.tier}
            title="EPS Growth"
            options={optionsEPSGrowth}
            tableDataList={epsDateList}
            highDataList={highEPSList}
            avgDataList={avgEPSList}
            lowDataList={lowEPSList}
            avgGrowthList={epsAvgGrowthList}
            graphType="growth"
          />
        </Lazy>

        <Lazy fadeOption={{ delay: 100, duration: 100 }} keep={true}>
          <EstimationGraph
            userTier={data?.user?.tier}
            title="Net Income"
            options={optionsNetIncome}
            tableDataList={netIncomeDateList}
            highDataList={highNetIncomeList}
            avgDataList={avgNetIncomeList}
            lowDataList={lowNetIncomeList}
          />
        </Lazy>

        <Lazy fadeOption={{ delay: 100, duration: 100 }} keep={true}>
          <EstimationGraph
            userTier={data?.user?.tier}
            title="Net Income Growth"
            options={optionsNetIncomeGrowth}
            tableDataList={netIncomeDateList}
            highDataList={highNetIncomeList}
            avgDataList={avgNetIncomeList}
            lowDataList={lowNetIncomeList}
            avgGrowthList={netIncomeAvgGrowthList}
            graphType="growth"
          />
        </Lazy>

        <Lazy fadeOption={{ delay: 100, duration: 100 }} keep={true}>
          <EstimationGraph
            userTier={data?.user?.tier}
            title="EBITDA"
            options={optionsEbitda}
            tableDataList={ebitdaDateList}
            highDataList={highEbitdaList}
            avgDataList={avgEbitdaList}
            lowDataList={lowEbitdaList}
          />
        </Lazy>

        <Lazy fadeOption={{ delay: 100, duration: 100 }} keep={true}>
          <EstimationGraph
            userTier={data?.user?.tier}
            title="EBITDA Growth"
            options={optionsEbitdaGrowth}
            tableDataList={ebitdaDateList}
            highDataList={highEbitdaList}
            avgDataList={avgEbitdaList}
            lowDataList={lowEbitdaList}
            avgGrowthList={ebitdaAvgGrowthList}
            graphType="growth"
          />
        </Lazy>
      </div>
    </div>
  </main>
</section>

<style>
  .app {
    height: 300px;
    max-width: 100%; /* Ensure chart width doesn't exceed the container */
  }

  @media (max-width: 640px) {
    .app {
      height: 210px;
    }
  }

  .chart {
    width: 100%;
  }
</style>
