<script lang="ts" setup>
import { computed, onMounted, ref, watchEffect } from "vue";
import Currency from "../components/Currency.vue";
import { useBudgetsStore } from "../stores/budget";
import { Category, useAccountStore } from "../stores/budget-account";
import { useSessionStore } from "../stores/session";
import Input from "../components/Input.vue";
import { POST } from "../api";

const props = defineProps<{
    budgetid: string,
    year: string,
    month: string,
}>()

const budgetsStore = useBudgetsStore();
const CurrentBudgetID = computed(() => budgetsStore.CurrentBudgetID);

const accountStore = useAccountStore();
const categoriesForMonth = accountStore.CategoriesForMonthAndGroup;

function GetCategories(group: string) {
    return [...categoriesForMonth(selected.value.Year, selected.value.Month, group)];
};

const groupsForMonth = accountStore.CategoryGroupsForMonth;
const GroupsForMonth = computed(() => {
    return [...groupsForMonth(selected.value.Year, selected.value.Month)];
});


const previous = computed(() => ({
    Year: new Date(selected.value.Year, selected.value.Month - 1, 1).getFullYear(),
    Month: new Date(selected.value.Year, selected.value.Month - 1, 1).getMonth(),
}));
const current = computed(() => ({
    Year: new Date().getFullYear(),
    Month: new Date().getMonth(),
}));
const selected = computed(() => ({
    Year: Number(props.year) ?? current.value.Year,
    Month: Number(props.month ?? current.value.Month)
}));
const next = computed(() => ({
    Year: new Date(selected.value.Year, Number(props.month) + 1, 1).getFullYear(),
    Month: new Date(selected.value.Year, Number(props.month) + 1, 1).getMonth(),
}));

watchEffect(() => {
    if (props.year != undefined && props.month != undefined)
        return useAccountStore().FetchMonthBudget(props.budgetid ?? "", Number(props.year), Number(props.month));
});

onMounted(() => {
    useSessionStore().setTitle("Budget for " + selected.value.Month + "/" + selected.value.Year);
})


const expandedGroups = ref<Map<string, boolean>>(new Map<string, boolean>())

function toggleGroup(group: { Name: string, Expand: boolean }) {
    expandedGroups.value.set(group.Name, !(expandedGroups.value.get(group.Name) ?? group.Expand))
}

function getGroupState(group: { Name: string, Expand: boolean }): boolean {
    return expandedGroups.value.get(group.Name) ?? group.Expand;
}

function assignedChanged(e : Event, category : Category){
    const target = e.target as HTMLInputElement;
    const value = target.valueAsNumber;
    POST("/budget/"+CurrentBudgetID.value+"/category/" + category.ID + "/" + selected.value.Year + "/" + (selected.value.Month+1),
    JSON.stringify({Assigned: category.Assigned}));
}

const budgeted = computed(() => accountStore.GetBudgeted(selected.value.Year, selected.value.Month))
</script>

<template>
  <h1>Budget for {{ selected.Month + 1 }}/{{ selected.Year }}</h1>
  <table class="inline-block">
    <tr>
      <td>
        Available last month:
      </td>
      <td class="text-right">
        <Currency :value="accountStore.Available-accountStore.OverspentLastMonth+budgeted.Assigned+budgeted.Deassigned" />
      </td>
    </tr>
    <tr>
      <td>
        Overspent last month:
      </td>
      <td class="text-right">
        <Currency :value="accountStore.OverspentLastMonth" />
      </td>
    </tr>
    <tr>
      <td>
        Budgeted this month:
      </td>
      <td class="text-right">
        <Currency :value="budgeted.Assigned+budgeted.Deassigned" />
      </td>
      <td class="text-sm pl-2">
        = <Currency :value="budgeted.Assigned" /> - <Currency :value="-budgeted.Deassigned" />
      </td>
    </tr>
    <tr class="font-bold">
      <td class="py-2">
        Available balance:
      </td>
      <td class="text-right">
        <Currency :value="accountStore.Available" />
      </td>
    </tr>
    <tr>
      <td>
        Activity:
      </td>
      <td class="text-right">
        <Currency :value="budgeted.Income + budgeted.Spent" />
      </td>
      <td class="text-sm pl-2">
        = <Currency :value="budgeted.Income" /> - <Currency :value="-1 * budgeted.Spent" />
      </td>
    </tr>
  </table>
  <div>
    <router-link
      :to="'/budget/' + CurrentBudgetID + '/budgeting/' + previous.Year + '/' + previous.Month"
    >
      &lt;&lt;
    </router-link>&nbsp;
    <router-link
      :to="'/budget/' + CurrentBudgetID + '/budgeting/' + current.Year + '/' + current.Month"
    >
      Current Month
    </router-link>&nbsp;
    <router-link
      :to="'/budget/' + CurrentBudgetID + '/budgeting/' + next.Year + '/' + next.Month"
    >
      &gt;&gt;
    </router-link>
  </div>
  <div
    id="content"
    class="container col-lg-12 grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-5"
  >
    <span class="hidden sm:block" />
    <span class="hidden lg:block text-right">Leftover</span>
    <span class="hidden sm:block text-right">Assigned</span>
    <span class="hidden sm:block text-right">Activity</span>
    <span class="hidden sm:block text-right">Available</span>
    <template
      v-for="group in GroupsForMonth"
      :key="group.Name"
    >
      <span
        class="text-lg font-bold mt-2"
        @click="toggleGroup(group)"
      >{{ (getGroupState(group) ? "−" : "+") + " " + group.Name }}</span>
      <Currency
        :value="group.AvailableLastMonth"
        class="hidden lg:block mt-2"
        positive-class="text-slate-500"
        negative-class="text-red-700 dark:text-red-400"
      />
      <Currency
        :value="group.Assigned"
        class="hidden sm:block mx-2 mt-2 text-right"
        positive-class="text-slate-500"
        negative-class="text-red-700 dark:text-red-400"
      />
      <Currency
        :value="group.Activity"
        class="hidden sm:block mt-2"
        positive-class="text-slate-500"
        negative-class="text-red-700 dark:text-red-400"
      />
      <Currency
        :value="group.Available"
        class="mt-2"
        positive-class="text-slate-500"
        negative-class="text-red-700 dark:text-red-400"
      />
      <template
        v-for="category in GetCategories(group.Name)"
        :key="category.ID"
      >
        <div
          v-if="getGroupState(group)"
          class="contents"
        >
          <span
            class="whitespace-nowrap overflow-hidden"
          >{{ category.Name }}</span>
          <Currency
            :value="category.AvailableLastMonth"
            class="hidden lg:block"
          />
          <Input
            v-model="category.Assigned"
            type="number"
            class="hidden sm:block mx-2 text-right"
            @input="(evt) => assignedChanged(evt, category)"
          />
          <Currency
            :value="category.Activity"
            class="hidden sm:block"
          />
          <Currency
            :value="accountStore.GetCategoryAvailable(category)"
          />
        </div>
      </template>
    </template>
  </div>
</template>
