"use client";

import { BillingLocation, YearMonth } from '@/app/lib/db-types';
import { FC, useEffect, useState } from 'react';
import { MonthLocationList } from '@/app/ui/MonthLocationList';
import { WithId } from 'mongodb';
import { MonthCardSkeleton } from './MonthCardSkeleton';

export interface HomePageProps {
}

const fetchAllLocations = async (year: number) => {
  const response = await fetch(`/api/all-locations/?year=${year}`);
  const { locations } : { locations: WithId<BillingLocation>[] } = await response.json();
  return locations;
}

const fetchAvailableYears = async () => {
  const response = await fetch(`/api/available-years/`);
  const { availableYears }: { availableYears: number[]} = await response.json();
  return availableYears;
}

export const HomePage:FC<HomePageProps> = () => {

  const [ homePageStatus, setHomePageStatus ] = useState<{
    status: "loading" | "loaded" | "error",
    availableYears: number[],
    locations: WithId<BillingLocation>[],
    error?: string
  }>({
    status: "loading",
    availableYears: [],
    locations: []
  });

  const {availableYears, locations, status, error} = homePageStatus;

  const year = new URLSearchParams(window.location.search).get('year');
  const currentYear = year ? parseInt(year, 10) : new Date().getFullYear();

  useEffect(() => {

    const fetchData = async () => {

      try {
        setHomePageStatus({
          availableYears: await fetchAvailableYears(),
          locations: await fetchAllLocations(currentYear),
          status: "loaded",
        });
      } catch (error: any) {
        setHomePageStatus({
          status: "error",
          availableYears: [],
          locations: [],
          error: error.message
        });
      }
    }

    fetchData();
  }, [currentYear]);

  if(status === "loading") {
    return (
      <>
        <MonthCardSkeleton checked={true} />
        <MonthCardSkeleton />
        <MonthCardSkeleton />
      </>
    );
  }

  if(status === "error") {
    return(<p className="text-center text-2xl text-red-500">{error}</p>);
  }

  // if the database is in it's initial state, show the add location button for the current month
  if(availableYears.length === 0) {
    return (<MonthLocationList />);
  }

  // group locations by month
  const months = locations.reduce((acc, location) => {
    const {year, month} =  location.yearMonth;
    const key = `${year}-${month}`;

    const locationsInMonth = acc[key];

    if(locationsInMonth) {
      return({
        ...acc,
        [key]: {
          yearMonth: location.yearMonth,
          locations: [...locationsInMonth.locations, location],
          monthlyExpense: locationsInMonth.monthlyExpense + location.bills.reduce((acc, bill) => bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0)
        }
      })
    }

    return({
      ...acc,
      [key]: {
        yearMonth: location.yearMonth,
        locations: [location],
        monthlyExpense: location.bills.reduce((acc, bill) => bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0)
      }
    });
  }, {} as {[key:string]:{
    yearMonth: YearMonth,
    locations: BillingLocation[],
    monthlyExpense: number
  } });

 return (
    <MonthLocationList availableYears={availableYears} months={months} />
  );
}

export default HomePage;