"use client";

import React, { useState } from "react";
import {
  useReactTable,
  flexRender,
  getCoreRowModel,
  ColumnDef,
} from "@tanstack/react-table";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/app/shadcn_components/ui/table";
import SelectComparisonModal from "./SelectComparisonModal";
import EpcBarChart from "./EpcBarChart";
import { DataItem, ChartData } from "@/app/portfolio/[slug]/utils";
import { UseQueryOptions, useQuery } from "@tanstack/react-query";

export async function getComparsionOverviewScenarioData(
  scenarioId: string
): Promise<Promise<DataItem[]>> {
  const url = process.env.URL || "" + `/api/portfolio/scenario/${scenarioId}`;

  // This is the client side counterpart to getOverviewScenarioData
  const response = await fetch(url, {
    method: "GET",
    headers: { "Content-Type": "application/json" },
    next: { revalidate: 60 },
  });
  if (!response.ok) {
    // Print the error
    console.error(response.statusText);
    throw new Error("Network response was not ok");
  }
  return response.json();
}

interface UseFetchScenarioSummaryProps {
  scenarioId: string; // Assuming scenarioId can be null to handle cases before it's available
  onSuccess: (data: DataItem[]) => void;
  options?: Omit<UseQueryOptions<DataItem[], Error>, "queryKey" | "queryFn">;
}

export const useFetchScenarioSummary = ({
  scenarioId,
  onSuccess,
}: UseFetchScenarioSummaryProps) => {
  return useQuery({
    queryKey: ["scenarioSummary", scenarioId],
    queryFn: () => getComparsionOverviewScenarioData(scenarioId as string), // Ensure non-null assertion or handle potential null inside the function
    onSuccess,
    enabled: scenarioId !== "no-id", // Ensure the query only runs when portfolioId is not null
  });
};

const shouldHighlightRow = (title: string) => {
  return [
    "Potential valuation improvement/unit - highly indicative EPC effect*",
    "Potential valuation return on investment - highly indicative EPC effect*",
  ].includes(title);
};

const formatCo2Title = (content: any) => {
  if (content === "CO2/unit") {
    return "CO₂/unit";
  }

  if (content === "£ per CO2 reduction") {
    return "£ per CO₂ reduction";
  }

  return content;
};

const SummaryTable = ({
  data,
  scenarios,
}: {
  data: DataItem[];
  scenarios: { name: string | null; id: bigint }[];
}) => {
  // TODO: Right now a user can ad multiple comparisons of the same column, we should prevent this

  const initialColumnSetup = () => {
    const initialColumns: ColumnDef<DataItem>[] = [
      {
        accessorKey: "title",
        header: () => null,
        cell: (info) => <b>{info.getValue() as string}</b>,
      },
    ];

    // Retrieve the scenario names
    const predefinedScenarios = data[0].scenarios.map(
      (scenario) => scenario.scenarioName
    );

    predefinedScenarios.forEach((scenarioName) => {
      initialColumns.push({
        id: scenarioName,
        header: () => <span>{scenarioName}</span>,
        accessorFn: (row) => {
          const scenarioData = row.scenarios.find(
            (s) => s.scenarioName === scenarioName
          )?.data;
          return scenarioData;
        },
        cell: (info) => {
          const value = info.getValue();
          // Render chart if data is array and matches the chart data structure, otherwise render as text
          return Array.isArray(value) && value[0]?.name ? (
            <EpcBarChart chartdata={value as ChartData[]} />
          ) : (
            <span>{value as String}</span>
          );
        },
      });
    });

    return initialColumns;
  };

  const [columns, setColumns] =
    useState<ColumnDef<DataItem>[]>(initialColumnSetup);

  const [managedData, setManagedData] = useState<DataItem[]>(data || []);

  const [isModalOpen, setIsModalOpen] = useState(false);

  const [selectedScenarioId, setSelectedScenarioId] = useState<string>("no-id");

  // Fetch and handle data when a new scenario is selected
  const {
    isLoading,
    error,
    data: fetchedData,
  } = useFetchScenarioSummary({
    scenarioId: selectedScenarioId,
    onSuccess: (fetchedData: DataItem[]) => {
      const updatedData = managedData.map((item) => ({
        ...item,
        scenarios: [
          ...item.scenarios,
          ...(fetchedData.find((fi) => fi.title === item.title)?.scenarios ||
            []),
        ],
      }));
      setManagedData(updatedData);
      if (fetchedData[0] && fetchedData[0].scenarios.length > 0) {
        addColumn(fetchedData[0].scenarios[0].scenarioName);
      }
    },
  });

  const table = useReactTable({
    data: managedData,
    columns: columns,
    getCoreRowModel: getCoreRowModel(),
  });

  const addColumn = (scenarioName: string) => {
    const newColumn: ColumnDef<DataItem> = {
      id: scenarioName.toLowerCase().replace(/\s+/g, "_"),
      accessorFn: (row) =>
        row.scenarios.find((s) => s.scenarioName === scenarioName)?.data,
      header: () => <span>{scenarioName}</span>,
      cell: (info) => {
        const value = info.getValue();
        return Array.isArray(value) ? (
          <EpcBarChart chartdata={value as ChartData[]} />
        ) : (
          <span>{String(value)}</span>
        );
      },
    };
    setColumns((oldColumns) => [...oldColumns, newColumn]);
  };

  return (
    <div className="my-8">
      <button
        onClick={() => setIsModalOpen(true)}
        className="mb-4 p-2 bg-brandbrown text-white rounded disabled:opacity-50"
        // If scenarios is empty, we disable this button
        disabled={scenarios.length === 0}
      >
        Add Comparison
      </button>
      <SelectComparisonModal
        isOpen={isModalOpen}
        setIsOpen={setIsModalOpen}
        scenarios={scenarios}
        onAddColumn={(id: string) => {
          setSelectedScenarioId(id);
        }}
      />

      <div className="text-black overflow-x-auto shadow-md sm:rounded-lg">
        <Table className="min-w-full">
          <TableHeader>
            {table.getHeaderGroups().map((headerGroup) => (
              <TableRow key={headerGroup.id}>
                {headerGroup.headers.map((header) => (
                  <TableHead key={header.id} className="px-6 py-3">
                    {flexRender(
                      header.column.columnDef.header,
                      header.getContext()
                    )}
                  </TableHead>
                ))}
              </TableRow>
            ))}
          </TableHeader>
          <TableBody>
            {table.getRowModel().rows.map((row) => (
              <TableRow
                key={row.id}
                style={
                  shouldHighlightRow(row.original.title)
                    ? { background: "#e1e1e1" }
                    : {}
                }
              >
                {row.getVisibleCells().map((cell) => (
                  <TableCell key={cell.id} className="px-6 py-4">
                    {flexRender(cell.column.columnDef.cell, {
                      ...cell.getContext(),
                      getValue: () => formatCo2Title(cell.getValue()),
                    })}
                  </TableCell>
                ))}
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </div>
    </div>
  );
};

export default SummaryTable;
