<script setup lang="ts">

import {computed, ref} from "vue";
import {storeToRefs} from "pinia";
import {isCombined, Ledger, LedgerType, LedgerTypes, useLedgersStore} from "./ledger";
import {Modal} from "@/components";
import LedgerLabel from "./LedgerLabel.vue";
import {PlusIcon, TrashIcon} from '@heroicons/vue/24/outline';
import LedgerSelect from "@/ledger/LedgerSelect.vue";

interface Props {
  ledgerId?: string;
}

const props = defineProps<Props>();

const ledgersStore = useLedgersStore();
const {ledgers} = storeToRefs(ledgersStore);
const {findById, findAllById, createMain, createCombined, updateMain, updateCombined} = ledgersStore;

const modalOpen = ref<boolean>(false);

const type = ref<LedgerType>(LedgerTypes.Main);
const name = ref("");
const members = ref<Ledger[]>([]);
const selectedLedger = ref<Ledger>();
const availableLedgers = computed(() => ledgers.value
    .filter((ledger) => selectedLedger.value === ledger)
    .filter(l => !members.value.includes(l)));


const addMember = () => {
  if (selectedLedger.value && !members.value.includes(selectedLedger.value)) {
    members.value = [...members.value, selectedLedger.value];
    selectedLedger.value = undefined;
  }
}

const open = () => {
  const ledger = isCreating.value ? undefined : findById(props.ledgerId);

  if (ledger) {
    type.value = ledger.type;
    name.value = ledger.name;
    members.value = isCombined(ledger) ? findAllById(ledger.memberLedgerIds) : [];
  } else {
    type.value = LedgerTypes.Main;
    name.value = "";
    members.value = [];
  }
  modalOpen.value = true;
}

const canSave = computed(() => name.value.trim().length > 0);
const isCreating = computed(() => props.ledgerId === undefined || props.ledgerId.length === 0);
const title = computed(() => {
  if (isCreating.value) {
    return `Creating ${type.value === LedgerTypes.Main ? 'Main' : 'Combined'} Ledger`
  }
  return `Updating ${name.value}`
})

const create = () => {
  if (type.value === LedgerTypes.Main) {
    createMain({name: name.value})
  } else {
    createCombined({name: name.value, memberLedgerIds: members.value.map(l => l.ledgerId)})
  }
}

const update = () => {
  if (type.value === LedgerTypes.Main) {
    updateMain(props.ledgerId, {name: name.value})
  } else {
    updateCombined(props.ledgerId, {name: name.value, memberLedgerIds: members.value.map(l => l.ledgerId)})
  }
}

const save = () => {
  if (!canSave.value) {
    return;
  }

  if (isCreating.value) {
    create();
  } else {
    update();
  }
  modalOpen.value = false;
}

defineExpose({ open });
</script>

<template>
  <Modal v-model:open="modalOpen">
    <div class="bg-slate-800 rounded pb-4 w-96">
      <span class="m-2">{{ title }}</span>
      <hr />
      <div class="mt-4">
        <div class="flex justify-center">
          <div class="flex bg-slate-600 rounded-s-md p-1">
            <button class="switch" :class="{active: type === LedgerTypes.Main}" @click="type = LedgerTypes.Main">Main</button>
          </div>
          <div class="switch flex bg-slate-600 rounded-e-md p-1">
            <button class="switch" :class="{active: type === LedgerTypes.Combined}" @click="type = LedgerTypes.Combined">Combined</button>
          </div>
        </div>
        <div class="m-4">
          Name:
          <div class="flex">
            <input type="text" class="flex grow" v-model="name" />
          </div>
        </div>
      </div>
      <div v-if="type === LedgerTypes.Combined" class="ms-4 mb-4">
        Member Ledgers:
        <div v-for="ledger in members" :key="ledger.ledgerId" class="flex">
          <LedgerLabel class="flex grow mb-2" :ledger="ledger" />
          <div class="flex justify-end me-4 ms-2">
            <button class="btn-icon" @click="members = members.filter(m => m !== ledger)"><TrashIcon /></button>
          </div>
        </div>
        <div v-if="availableLedgers.length" class="flex">
          <LedgerSelect v-model="selectedLedger" class="grow" :ledgers="availableLedgers" />
          <div class="flex justify-end me-4 ms-2">
            <button class="btn-icon" @click="addMember"><PlusIcon /></button>
          </div>
        </div>
      </div>
      <div class="flex justify-end">
        <button class="me-4" @click="save" :disabled="!canSave">Save</button>
      </div>
    </div>
  </Modal>
</template>

<style scoped>
@reference "tailwindcss";

button.switch {
  @apply flex items-center px-4 rounded-md bg-slate-600;
  &.active {
    @apply bg-emerald-500;
  }
}
</style>