import { BalanceToBudgetRatio } from "../../types/balanceToBudgetRatio";
import { Category } from "../../types/category";
import { Group } from "../../types/group";
import { groupCategories } from "../../util/groupCategories";
import './Histogram.scss';

function Histogram({ categories }: Props) {
  if (categories === null) {
    return (
      <p>No categories to show</p>
    );
  }

  const balanceToBudgetRatioNormaliser = BalanceToBudgetRatio.makeNormaliser(...categories.map(c => c.balanceToBudgetRatio));
  for (const category of categories) {
    category.balanceToBudgetRatio = balanceToBudgetRatioNormaliser(category.balanceToBudgetRatio);
  }

  const groups = [...groupCategories(categories)];

  return (
    <table>
      <thead>
        <tr>
          <th>Category</th>
          <th>Balance-to-Budget Ratio</th>
          <th>Balance</th>
        </tr>
      </thead>
      {
        groups.map(g => <RowGroup group={g} />)
      }
    </table>
  );
}

function RowGroup({ group }: GroupProps) {
  return (
    <tbody>
      <tr role="heading" aria-level="3">{group.name}</tr>
      {
        group.categories
          .sort((c1, c2) => BalanceToBudgetRatio.compare(c1.balanceToBudgetRatio, c2.balanceToBudgetRatio))
          .map((category) => Row({ category }))
      }
    </tbody>
  );
}

function Row({ category }: RowProps) {
  return (
    <tr>
      <td class="name">{category.name}</td>
      <td
        class={`ratio ratio--${category.balanceToBudgetRatio?.recommendedAction ?? ''}`}
        style={`--normal-abs-ratio: ${Math.abs(category.balanceToBudgetRatio?.normalisedRatio ?? 0)};`}
      >
        <span class="ratio__text">
          {category.balanceToBudgetRatio?.toString() ?? ''}
        </span>
        <span class="ratio__bar"></span>
      </td>
      <td class="balance">{category.currentBalance.toString()}</td>
    </tr>
  );
}

type Props = {
  categories: Category[] | null,
};

type GroupProps = {
  group: Group;
}

type RowProps = {
  category: Category,
};

export default Histogram;
