<template>
  <UCard>
    <template #header>
      <div class="flex items-center justify-between">
        <div>
          <h3 class="text-lg font-semibold text-neutral-900 dark:text-white">
            One-Off Transactions
          </h3>
          <p class="text-sm text-neutral-600 dark:text-neutral-400 mt-1">
            Add one-time income or expense transactions with expected dates.
          </p>
        </div>
        <UButton @click="addEvent" size="sm" icon="i-heroicons-plus">
          Add Transaction
        </UButton>
      </div>
    </template>

    <!-- Empty state -->
    <div v-if="sortedEvents.length === 0" class="text-center py-8">
      <UIcon
        name="i-heroicons-banknotes"
        class="w-12 h-12 mx-auto text-neutral-400 mb-4" />
      <h4 class="text-lg font-medium text-neutral-900 dark:text-white mb-2">
        No transactions yet
      </h4>
      <p class="text-neutral-600 dark:text-neutral-400 mb-4">
        Add one-off income or expense transactions.
      </p>
      <UButton @click="addEvent" color="primary">
        Add Your First Transaction
      </UButton>
    </div>

    <!-- Events list -->
    <div v-else class="space-y-6">
      <!-- Month grouping -->
      <div
        v-for="monthGroup in eventsByMonth"
        :key="monthGroup.month"
        class="space-y-3">
        <!-- Month header -->
        <div
          class="flex items-center justify-between py-2 border-b border-neutral-200 dark:border-neutral-700">
          <h4 class="font-medium text-neutral-900 dark:text-white">
            {{ monthGroup.monthName }}
          </h4>
          <div class="flex items-center gap-3">
            <UBadge variant="subtle" color="neutral">
              {{ monthGroup.events.length }} transaction{{
                monthGroup.events.length !== 1 ? "s" : ""
              }}
            </UBadge>
            <div
              class="text-sm font-medium"
              :class="
                monthGroup.netAmount >= 0 ? 'text-green-600' : 'text-red-600'
              ">
              {{ monthGroup.netAmount >= 0 ? "+" : ""
              }}{{ formatCurrency(monthGroup.netAmount) }}
            </div>
          </div>
        </div>

        <!-- Events in this month -->
        <div class="space-y-3">
          <UCard
            v-for="event in monthGroup.events"
            :key="event.id"
            :ui="{
              background:
                event.type === 'income'
                  ? 'bg-green-50 dark:bg-green-900/20'
                  : 'bg-red-50 dark:bg-red-900/20',
              ring:
                event.type === 'income'
                  ? 'ring-green-200 dark:ring-green-800'
                  : 'ring-red-200 dark:ring-red-800',
            }">
            <UForm :state="event" @submit="() => {}">
              <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
                <!-- Category -->
                <UFormField label="Category" name="category" required>
                  <USelect
                    v-model="event.category"
                    :options="categoryOptions"
                    @update:model-value="
                      updateEvent(event.id, { category: $event })
                    " />
                </UFormField>

                <!-- Name -->
                <UFormField label="Name" name="name" required>
                  <UInput
                    v-model="event.name"
                    placeholder="e.g., Equipment purchase"
                    @update:model-value="
                      updateEvent(event.id, { name: $event })
                    " />
                </UFormField>

                <!-- Type -->
                <UFormField label="Type" name="type" required>
                  <USelect
                    v-model="event.type"
                    :options="typeOptions"
                    @update:model-value="
                      updateEvent(event.id, { type: $event })
                    " />
                </UFormField>

                <!-- Amount -->
                <UFormField label="Amount" name="amount" required>
                  <UInput
                    v-model="event.amount"
                    type="number"
                    placeholder="5000"
                    @update:model-value="
                      updateEvent(event.id, { amount: Number($event) })
                    ">
                    <template #leading>
                      <span class="text-neutral-500">$</span>
                    </template>
                  </UInput>
                </UFormField>
              </div>

              <!-- Date Expected -->
              <div class="mt-4">
                <UFormField label="Date Expected" name="dateExpected" required>
                  <UInput
                    v-model="event.dateExpected"
                    type="date"
                    @update:model-value="
                      updateEventWithDate(event.id, $event)
                    " />
                </UFormField>
              </div>
            </UForm>

            <template #footer>
              <div class="flex items-center justify-between">
                <UButton
                  variant="ghost"
                  color="red"
                  size="sm"
                  icon="i-heroicons-trash"
                  @click="removeEvent(event.id)">
                  Delete
                </UButton>
                <UDropdown :items="getEventActions(event)">
                  <UButton
                    variant="ghost"
                    color="neutral"
                    size="sm"
                    icon="i-heroicons-ellipsis-horizontal" />
                </UDropdown>
              </div>
            </template>
          </UCard>
        </div>
      </div>

      <!-- Summary -->
      <UCard>
        <div class="flex items-center justify-between">
          <span class="font-medium text-neutral-900 dark:text-white">
            Total {{ sortedEvents.length }} transaction{{
              sortedEvents.length !== 1 ? "s" : ""
            }}
          </span>
          <span
            class="text-lg font-bold"
            :class="totalAnnualImpact >= 0 ? 'text-green-600' : 'text-red-600'">
            {{ totalAnnualImpact >= 0 ? "+" : ""
            }}{{ formatCurrency(totalAnnualImpact) }}
          </span>
        </div>
      </UCard>
    </div>
  </UCard>
</template>

<script setup lang="ts">
import type { OneOffEvent } from "~/types/cash";

const cashStore = useCashStore();

// Constants
const monthNames = [
  "January",
  "February",
  "March",
  "April",
  "May",
  "June",
  "July",
  "August",
  "September",
  "October",
  "November",
  "December",
];

const typeOptions = [
  { label: "Income", value: "income" },
  { label: "Expense", value: "expense" },
];

const categoryOptions = [
  { label: "Equipment", value: "Equipment" },
  { label: "Marketing", value: "Marketing" },
  { label: "Legal", value: "Legal" },
  { label: "Contractors", value: "Contractors" },
  { label: "Office", value: "Office" },
  { label: "Development", value: "Development" },
  { label: "Other", value: "Other" },
];

// Computed
const { oneOffEvents } = storeToRefs(cashStore);

const sortedEvents = computed(() => {
  return oneOffEvents.value
    .slice()
    .sort((a, b) => a.month - b.month || a.name.localeCompare(b.name));
});

const eventsByMonth = computed(() => {
  const groups: Record<number, OneOffEvent[]> = {};

  sortedEvents.value.forEach((event) => {
    if (!groups[event.month]) {
      groups[event.month] = [];
    }
    groups[event.month].push(event);
  });

  return Object.entries(groups)
    .map(([month, events]) => {
      const monthNum = parseInt(month);
      const netAmount = events.reduce((sum, event) => {
        return sum + (event.type === "income" ? event.amount : -event.amount);
      }, 0);

      return {
        month: monthNum,
        monthName: monthNames[monthNum],
        events,
        netAmount,
      };
    })
    .sort((a, b) => a.month - b.month);
});

const totalIncome = computed(() => {
  return oneOffEvents.value
    .filter((e) => e.type === "income")
    .reduce((sum, e) => sum + e.amount, 0);
});

const totalExpenses = computed(() => {
  return oneOffEvents.value
    .filter((e) => e.type === "expense")
    .reduce((sum, e) => sum + e.amount, 0);
});

const totalAnnualImpact = computed(
  () => totalIncome.value - totalExpenses.value
);

// Methods
function addEvent() {
  const currentMonth = new Date().getMonth();
  const today = new Date().toISOString().split("T")[0];
  cashStore.addOneOffEvent({
    name: "",
    type: "income",
    amount: 0,
    category: "Other",
    dateExpected: today,
  });
}

function updateEvent(eventId: string, updates: Partial<OneOffEvent>) {
  cashStore.updateOneOffEvent(eventId, updates);
}

function updateEventWithDate(eventId: string, dateExpected: string) {
  const eventDate = new Date(dateExpected);
  const month = eventDate.getMonth();
  cashStore.updateOneOffEvent(eventId, { dateExpected, month });
}

function removeEvent(eventId: string) {
  cashStore.removeOneOffEvent(eventId);
}

function getEventActions(event: OneOffEvent) {
  return [
    [
      {
        label: "Move to Different Month",
        icon: "i-heroicons-arrow-right",
        click: () => moveToMonth(event.id),
      },
    ],
    [
      {
        label: "Duplicate Event",
        icon: "i-heroicons-document-duplicate",
        click: () => duplicateEvent(event),
      },
    ],
  ];
}

function moveToMonth(eventId: string) {
  // This could open a month selector modal
  // For now, just move to next month
  const event = oneOffEvents.value.find((e) => e.id === eventId);
  if (event) {
    const newMonth = (event.month + 1) % 12;
    updateEvent(eventId, { month: newMonth });
  }
}

function duplicateEvent(event: OneOffEvent) {
  cashStore.addOneOffEvent({
    name: `${event.name} (Copy)`,
    type: event.type,
    amount: event.amount,
    category: event.category,
    dateExpected: event.dateExpected,
  });
}

function getDateValue(dateExpected: string | undefined): string {
  if (!dateExpected) {
    return new Date().toISOString().split("T")[0];
  }
  return dateExpected;
}

function formatCurrency(amount: number): string {
  return new Intl.NumberFormat("en-US", {
    style: "currency",
    currency: "USD",
    maximumFractionDigits: 0,
  }).format(Math.abs(amount));
}
</script>
