import { m as Alpine } from './vendor-ui-CflGdlft.js';
import { apiGet, apiPost, money, monthNow } from './app-api.js';

function registerOrderTable() {
  if (!Alpine.store('invoiceDetail')) {
    Alpine.store('invoiceDetail', {
      currentInvoice: null,
      currentPayments: [],
    });
  }

  Alpine.data('invoicesTable', () => ({
    orders: [],
    filteredOrders: [],
    selectedOrders: [],
    currentPage: 1,
    itemsPerPage: 10,
    searchQuery: '',
    statusFilter: '',
    dateFilter: '',
    sortField: 'due_date',
    sortDirection: 'asc',
    isLoading: false,
    billingMonth: monthNow(),

    currentInvoice: null,
    currentPayments: [],

    charts: {
      revenue: null,
      status: null,
    },

    async init() {
      await this.refresh();
      await this.loadCharts();
    },

    money(v) {
      return money(v);
    },

    async sendPaylinks(channel) {
      if (!this.selectedOrders || this.selectedOrders.length === 0) {
        if (window.AdminApp?.notificationManager?.warning) window.AdminApp.notificationManager.warning('Select invoices first');
        else alert('Select invoices first');
        return;
      }

      try {
        const res = await apiPost('/notifications/send-paylink', {
          billing_month: this.billingMonth,
          channel,
          invoice_ids: this.selectedOrders,
        });

        const msg = `Sent: ${res.sent || 0}, Failed: ${res.failed || 0}`;
        if (window.AdminApp?.notificationManager?.success) window.AdminApp.notificationManager.success(msg);
        else alert(msg);

        this.selectedOrders = [];
      } catch (e) {
        const msg = e?.message ? String(e.message) : 'Failed to send paylinks';
        if (window.AdminApp?.notificationManager?.error) window.AdminApp.notificationManager.error(msg);
        else alert(msg);
      }
    },

    async refresh() {
      this.isLoading = true;
      try {
        await apiPost('/billing/generate', { billing_month: this.billingMonth });
        const res = await apiGet(`/invoices?billing_month=${encodeURIComponent(this.billingMonth)}`);
        const invoices = res.data || [];

        this.orders = invoices.map(i => ({
          id: i.invoice_id,
          orderNumber: `INV-${i.invoice_id}`,
          customer: {
            name: `${i.first_name} ${i.last_name}`.trim(),
            email: i.guardian_email || i.learner_email || '',
            avatar: './assets/images/avatar-placeholder.svg',
          },
          itemCount: 1,
          items: [{ name: 'Monthly Tuition' }],
          total: Number(i.amount_due || 0),
          paid: Number(i.amount_paid || 0),
          balance: Number(i.balance || 0),
          status: (i.status || (i.balance <= 0 ? 'paid' : (i.amount_paid > 0 ? 'partial' : 'unpaid'))),
          orderDate: i.due_date,
          _raw: i,
        }));

        this.filterOrders();
        await this.loadCharts();
      } finally {
        this.isLoading = false;
      }
    },

    async loadCharts() {
      try {
        const [trend, status] = await Promise.all([
          apiGet('/stats/revenue-trend?months=6'),
          apiGet(`/stats/invoice-status?billing_month=${encodeURIComponent(this.billingMonth)}`),
        ]);

        this.renderRevenueTrend(trend.data || []);
        this.renderStatusChart(status.data || []);
      } catch (e) {
        // silent: charts are non-critical
      }
    },

    renderRevenueTrend(rows) {
      const el = document.getElementById('revenueTrendChart');
      if (!el || typeof ApexCharts === 'undefined') return;

      const categories = rows.map(r => r.billing_month);
      const series = rows.map(r => Number(r.paid || 0));

      const options = {
        series: [{ name: 'Paid', data: series }],
        chart: { type: 'area', height: 300, toolbar: { show: false } },
        dataLabels: { enabled: false },
        stroke: { curve: 'smooth', width: 2 },
        xaxis: { categories },
        yaxis: { labels: { formatter: v => Number(v).toLocaleString() } },
        tooltip: { y: { formatter: v => `GHS ${Number(v).toLocaleString()}` } },
        colors: ['#6366f1'],
        fill: { type: 'gradient', gradient: { shadeIntensity: 1, opacityFrom: 0.35, opacityTo: 0.05 } },
      };

      if (this.charts.revenue) {
        this.charts.revenue.updateOptions(options);
      } else {
        this.charts.revenue = new ApexCharts(el, options);
        this.charts.revenue.render();
      }
    },

    renderStatusChart(rows) {
      const el = document.getElementById('invoiceStatusChart');
      if (!el || typeof ApexCharts === 'undefined') return;

      const map = new Map(rows.map(r => [r.status, Number(r.count || 0)]));
      const labels = ['unpaid', 'partial', 'paid', 'void'];
      const series = labels.map(l => map.get(l) || 0);

      const options = {
        series,
        chart: { type: 'donut', height: 300 },
        labels,
        colors: ['#ef4444', '#f59e0b', '#22c55e', '#9ca3af'],
        legend: { position: 'bottom' },
      };

      if (this.charts.status) {
        this.charts.status.updateOptions(options);
      } else {
        this.charts.status = new ApexCharts(el, options);
        this.charts.status.render();
      }
    },

    filterOrders() {
      const q = this.searchQuery.trim().toLowerCase();
      this.filteredOrders = this.orders.filter(o => {
        const matchesSearch = q === '' ||
          (o.orderNumber || '').toLowerCase().includes(q) ||
          (o.customer.name || '').toLowerCase().includes(q) ||
          (o.customer.email || '').toLowerCase().includes(q);

        const matchesStatus = this.statusFilter === '' || o.status === this.statusFilter;
        return matchesSearch && matchesStatus;
      });

      this.sortOrders();
      this.currentPage = 1;
    },

    sortBy(field) {
      if (this.sortField === field) {
        this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
      } else {
        this.sortField = field;
        this.sortDirection = 'asc';
      }
      this.sortOrders();
    },

    sortOrders() {
      this.filteredOrders.sort((a, b) => {
        let aVal = a[this.sortField];
        let bVal = b[this.sortField];
        if (typeof aVal === 'string') aVal = aVal.toLowerCase();
        if (typeof bVal === 'string') bVal = bVal.toLowerCase();
        if (this.sortDirection === 'asc') return aVal > bVal ? 1 : -1;
        return aVal < bVal ? 1 : -1;
      });
    },

    get paginatedOrders() {
      const start = (this.currentPage - 1) * this.itemsPerPage;
      const end = start + this.itemsPerPage;
      return this.filteredOrders.slice(start, end);
    },

    get totalPages() {
      return Math.ceil(this.filteredOrders.length / this.itemsPerPage);
    },

    get visiblePages() {
      const delta = 2;
      const range = [];
      const rangeWithDots = [];

      for (let i = Math.max(2, this.currentPage - delta); i <= Math.min(this.totalPages - 1, this.currentPage + delta); i++) {
        range.push(i);
      }

      if (this.currentPage - delta > 2) rangeWithDots.push(1, '...');
      else rangeWithDots.push(1);

      rangeWithDots.push(...range);

      if (this.currentPage + delta < this.totalPages - 1) rangeWithDots.push('...', this.totalPages);
      else if (this.totalPages > 1) rangeWithDots.push(this.totalPages);

      return rangeWithDots.filter((v, i, a) => a.indexOf(v) === i && v <= this.totalPages);
    },

    goToPage(page) {
      if (page >= 1 && page <= this.totalPages) this.currentPage = page;
    },

    toggleAll(checked) {
      this.selectedOrders = checked ? this.paginatedOrders.map(o => o.id) : [];
    },

    exportOrders() {
      const headers = ['Invoice', 'Learner', 'Guardian Email', 'Due', 'Paid', 'Balance', 'Status'];
      const rows = this.filteredOrders.map(o => [
        o.orderNumber,
        o.customer.name,
        o.customer.email,
        money(o.total),
        money(o.paid),
        money(o.balance),
        o.status,
      ]);
      const csv = [headers, ...rows].map(r => r.map(v => String(v ?? '').replaceAll(',', ' ')).join(',')).join('\n');
      const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
      const link = document.createElement('a');
      link.href = URL.createObjectURL(blob);
      link.download = `invoices-${this.billingMonth}.csv`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    },

    async viewOrder(order) {
      try {
        const res = await apiGet(`/invoices/detail?invoice_id=${encodeURIComponent(order.id)}`);
        this.$store.invoiceDetail.currentInvoice = res.invoice || null;
        this.$store.invoiceDetail.currentPayments = res.payments || [];

        const modalEl = document.getElementById('invoiceDetailModal');
        if (modalEl && window.bootstrap?.Modal) {
          window.bootstrap.Modal.getOrCreateInstance(modalEl).show();
        }
      } catch (e) {
        window.AdminApp?.notificationManager?.error(e.message);
      }
    },

    async printInvoice(order) {
      const max = Number(order?.balance || 0);
      const amount = prompt(`Enter manual payment amount (max ${money(max)}):`);
      if (!amount) return;
      const n = Number(amount);
      if (!Number.isFinite(n) || n <= 0) {
        window.AdminApp?.notificationManager?.warning('Invalid amount');
        return;
      }

      if (Number.isFinite(max) && max > 0 && n - max > 0.00001) {
        window.AdminApp?.notificationManager?.warning(`Amount cannot exceed outstanding balance (${money(max)})`);
        return;
      }

      try {
        await apiPost('/payments/manual', {
          invoice_id: order.id,
          amount: n,
          channel: 'cash',
          received_by: 'admin',
          notes: 'Manual entry',
        });
        await this.refresh();
        window.AdminApp?.notificationManager?.success('Payment recorded');
      } catch (e) {
        window.AdminApp?.notificationManager?.error(e.message);
      }
    },

    trackOrder() {
      window.AdminApp?.notificationManager?.info('Use View Details to open Paystack link');
    },

    cancelOrder() {
      window.AdminApp?.notificationManager?.warning('Void invoice not implemented yet');
    },

    bulkAction() {
      window.AdminApp?.notificationManager?.info('Bulk updates not used on invoices');
    },

    get stats() {
      const total = this.orders.length;
      const pending = this.orders.filter(o => o.status === 'unpaid').length;
      const shipped = this.orders.filter(o => o.status === 'partial').length;
      const revenue = this.orders.reduce((a, o) => a + (o.paid || 0), 0);
      return { total, pending, shipped, revenue };
    },

    get statusStats() {
      const counts = {
        unpaid: this.orders.filter(o => o.status === 'unpaid').length,
        partial: this.orders.filter(o => o.status === 'partial').length,
        paid: this.orders.filter(o => o.status === 'paid').length,
      };
      const total = this.orders.length || 1;
      return Object.entries(counts).map(([name, count]) => ({
        name,
        count,
        percentage: Math.round((count / total) * 100),
      }));
    },
  }));
}

document.addEventListener('alpine:init', registerOrderTable);

try {
  registerOrderTable();
} catch {
  // noop
}
