import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { invoke } from '@tauri-apps/api/core'
import { handleInvokeError } from '../utils/errorHandler'

export interface Invoice {
  id?: number
  client_id: number
  invoice_number: string
  date: string
  due_date?: string
  subtotal: number
  tax_rate: number
  tax_amount: number
  discount: number
  total: number
  notes?: string
  status: string
  template_id?: string
}

export interface InvoiceItem {
  id?: number
  invoice_id: number
  description: string
  quantity: number
  rate: number
  amount: number
  time_entry_id?: number
}

export const useInvoicesStore = defineStore('invoices', () => {
  const invoices = ref<Invoice[]>([])
  const loading = ref(false)

  async function fetchInvoices() {
    loading.value = true
    try {
      invoices.value = await invoke<Invoice[]>('get_invoices')
    } catch (error) {
      handleInvokeError(error, 'Failed to fetch invoices', () => fetchInvoices())
    } finally {
      loading.value = false
    }
  }

  async function createInvoice(invoice: Invoice): Promise<number | null> {
    try {
      const id = await invoke<number>('create_invoice', { invoice })
      invoices.value.unshift({ ...invoice, id: Number(id) })
      return Number(id)
    } catch (error) {
      handleInvokeError(error, 'Failed to create invoice')
      return null
    }
  }

  async function updateInvoice(invoice: Invoice): Promise<boolean> {
    try {
      await invoke('update_invoice', { invoice })
      const index = invoices.value.findIndex(i => i.id === invoice.id)
      if (index !== -1) {
        invoices.value[index] = invoice
      }
      return true
    } catch (error) {
      handleInvokeError(error, 'Failed to update invoice')
      return false
    }
  }

  async function updateInvoiceTemplate(id: number, templateId: string): Promise<boolean> {
    try {
      await invoke('update_invoice_template', { id, templateId })
      const index = invoices.value.findIndex(i => i.id === id)
      if (index !== -1) {
        invoices.value[index].template_id = templateId
      }
      return true
    } catch (error) {
      handleInvokeError(error, 'Failed to update invoice template')
      return false
    }
  }

  async function deleteInvoice(id: number): Promise<boolean> {
    try {
      await invoke('delete_invoice', { id })
      invoices.value = invoices.value.filter(i => i.id !== id)
      return true
    } catch (error) {
      handleInvokeError(error, 'Failed to delete invoice')
      return false
    }
  }

  async function getInvoiceItems(invoiceId: number): Promise<InvoiceItem[]> {
    try {
      return await invoke<InvoiceItem[]>('get_invoice_items', { invoiceId })
    } catch (error) {
      handleInvokeError(error, 'Failed to fetch invoice items')
      return []
    }
  }

  async function createInvoiceItem(item: InvoiceItem): Promise<number | null> {
    try {
      return await invoke<number>('create_invoice_item', { item })
    } catch (error) {
      handleInvokeError(error, 'Failed to create invoice item')
      return null
    }
  }

  async function saveInvoiceItems(invoiceId: number, items: { description: string; quantity: number; unit_price: number; time_entry_id?: number }[]): Promise<void> {
    try {
      await invoke('save_invoice_items_batch', {
        invoiceId,
        items: items.map(item => ({
          description: item.description,
          quantity: item.quantity,
          unit_price: item.unit_price,
          time_entry_id: item.time_entry_id || null,
        })),
      })
    } catch (error) {
      handleInvokeError(error, 'Failed to save invoice items')
      throw error
    }
  }

  async function updateStatus(id: number, status: string): Promise<boolean> {
    try {
      await invoke('update_invoice_status', { id, status })
      const idx = invoices.value.findIndex(i => i.id === id)
      if (idx !== -1) invoices.value[idx].status = status
      return true
    } catch (error) {
      handleInvokeError(error, 'Failed to update invoice status')
      return false
    }
  }

  async function checkOverdue(): Promise<number> {
    try {
      const today = new Date().toISOString().split('T')[0]
      const count = await invoke<number>('check_overdue_invoices', { today })
      if (count > 0) await fetchInvoices()
      return count
    } catch {
      return 0
    }
  }

  const overdueCount = computed(() => invoices.value.filter(i => i.status === 'overdue').length)

  const groupedByStatus = computed(() => {
    const groups: Record<string, Invoice[]> = { draft: [], sent: [], overdue: [], paid: [] }
    for (const inv of invoices.value) {
      if (groups[inv.status]) groups[inv.status].push(inv)
      else groups.draft.push(inv)
    }
    return groups
  })

  return {
    invoices,
    loading,
    overdueCount,
    groupedByStatus,
    fetchInvoices,
    createInvoice,
    updateInvoice,
    updateInvoiceTemplate,
    deleteInvoice,
    getInvoiceItems,
    createInvoiceItem,
    saveInvoiceItems,
    updateStatus,
    checkOverdue
  }
})
