import { useEffect, useState } from 'react'
import { Link, useNavigate, useParams } from 'react-router-dom'
import { ArrowLeft, Copy, Eye, FilePlus2, Pencil, Trash2 } from 'lucide-react'
import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal'
import { Modal } from '../components/Modal'
import { isEmptyRichText } from '../components/RichTextEditor'
import { useToast } from '../context/ToastContext'
import { ApiError, isAbortError } from '../lib/api'
import { getPlatformInvoicePublicUrl } from '../lib/config'
import { getBusiness, type BusinessDetail } from '../services/businessService'
import {
  deleteBusinessInvoice,
  listBusinessInvoices,
  updateBusinessInvoiceStatus,
} from '../services/invoiceService'
import type { Invoice, InvoiceStatus } from '../types/invoice'
import { formatIrtPrice } from '../utils/irtPrice'
import { Pagination } from '@meshkee/dashboard-ui'
import pageStyles from '../components/PageContent.module.css'
import tableStyles from './BusinessesPage.module.css'
import styles from './BusinessInvoicesPage.module.css'

const STATUS_OPTIONS: InvoiceStatus[] = ['draft', 'issued', 'approved', 'paid', 'cancelled']

function formatDate(value: string) {
  const d = new Date(value)
  if (Number.isNaN(d.getTime())) return value
  return d.toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'short',
    day: '2-digit',
  })
}

function statusLabel(status: InvoiceStatus) {
  return status.charAt(0).toUpperCase() + status.slice(1)
}

function statusClass(status: InvoiceStatus) {
  return styles[`status_${status}` as keyof typeof styles] ?? styles.status_draft
}

function canEditInvoice(status: InvoiceStatus) {
  return status !== 'approved'
}

function allowedStatusOptions(current: InvoiceStatus): InvoiceStatus[] {
  if (current !== 'approved') return STATUS_OPTIONS
  return STATUS_OPTIONS.filter(
    (option) => option === 'approved' || option === 'paid' || option === 'cancelled',
  )
}

export function BusinessInvoicesPage() {
  const { businessId = '' } = useParams()
  const navigate = useNavigate()
  const { showToast } = useToast()

  const [business, setBusiness] = useState<BusinessDetail | null>(null)
  const [invoices, setInvoices] = useState<Invoice[]>([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState('')
  const [page, setPage] = useState(1)
  const [totalPages, setTotalPages] = useState(1)
  const [total, setTotal] = useState(0)

  const [detailInvoice, setDetailInvoice] = useState<Invoice | null>(null)
  const [statusTarget, setStatusTarget] = useState<Invoice | null>(null)
  const [statusUpdating, setStatusUpdating] = useState<InvoiceStatus | null>(null)
  const [removeTarget, setRemoveTarget] = useState<Invoice | null>(null)

  async function reload(signal?: AbortSignal) {
    if (!businessId) return
    setLoading(true)
    setError('')
    try {
      const [biz, list] = await Promise.all([
        getBusiness(businessId, signal),
        listBusinessInvoices(businessId, { page, pageSize: 20 }, signal),
      ])
      setBusiness(biz)
      setInvoices(list.items)
      setTotalPages(list.totalPages)
      setTotal(list.total)
    } catch (err) {
      if (isAbortError(err)) return
      setError(err instanceof ApiError ? err.message : 'Unable to load invoices.')
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    const controller = new AbortController()
    void reload(controller.signal)
    return () => controller.abort()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [businessId, page])

  function openStatusModal(invoice: Invoice) {
    setStatusTarget(invoice)
  }

  async function handleStatusSelect(next: InvoiceStatus) {
    if (!statusTarget || statusUpdating) return
    if (next === statusTarget.status) {
      setStatusTarget(null)
      return
    }

    setStatusUpdating(next)
    try {
      const updated = await updateBusinessInvoiceStatus(businessId, statusTarget.id, {
        status: next,
      })
      setInvoices((rows) => rows.map((row) => (row.id === updated.id ? updated : row)))
      setDetailInvoice((current) => (current?.id === updated.id ? updated : current))
      showToast('Invoice status updated.', 'success')
      setStatusTarget(null)
    } catch (err) {
      showToast(err instanceof ApiError ? err.message : 'Unable to update status.', 'error')
    } finally {
      setStatusUpdating(null)
    }
  }

  async function handleRemove() {
    if (!removeTarget) return
    try {
      await deleteBusinessInvoice(businessId, removeTarget.id)
      showToast('Invoice removed.', 'success')
      setRemoveTarget(null)
      if (detailInvoice?.id === removeTarget.id) setDetailInvoice(null)
      await reload()
    } catch (err) {
      showToast(err instanceof ApiError ? err.message : 'Unable to remove invoice.', 'error')
    }
  }

  async function copyPublicLink(invoice: Invoice) {
    const url = invoice.publicUrl || getPlatformInvoicePublicUrl(invoice.publicId)
    try {
      await navigator.clipboard.writeText(url)
      showToast('Invoice link copied.', 'success')
    } catch {
      showToast('Unable to copy link.', 'error')
    }
  }

  function invoicePublicUrl(invoice: Invoice) {
    // Prefer local/dev origin so the public show page is reachable while designing.
    if (import.meta.env.DEV || import.meta.env.VITE_INVOICE_PUBLIC_BASE_URL) {
      return getPlatformInvoicePublicUrl(invoice.publicId)
    }
    return invoice.publicUrl || getPlatformInvoicePublicUrl(invoice.publicId)
  }

  const businessName = business?.name || business?.nameFa || 'Business'

  return (
    <main className={pageStyles.content}>
      <div className={pageStyles.pageHeader}>
        <div>
          <Link to="/businesses" className={styles.backLink}>
            <ArrowLeft size={16} />
            Back to businesses
          </Link>
          <h2 className={pageStyles.pageTitle}>Invoices · {businessName}</h2>
          <p className={pageStyles.pageSubtitle}>
            Select an invoice template and edit it for this business, or create a blank invoice.
          </p>
        </div>
        <button
          type="button"
          className={`${tableStyles.btn} ${tableStyles.btnPrimary}`}
          onClick={() => navigate(`/businesses/${businessId}/invoices/new`)}
        >
          <FilePlus2 size={16} />
          Issue invoice
        </button>
      </div>

      {error ? <p className={styles.alertError}>{error}</p> : null}

      <div className={tableStyles.tableWrap}>
        <div className={tableStyles.tableHeader}>
          <div className={tableStyles.tableHeaderTitle}>Invoices</div>
          <div className={tableStyles.meta}>
            {loading ? 'Loading…' : `${total} invoice${total === 1 ? '' : 's'}`}
          </div>
        </div>
        <table className={tableStyles.table}>
          <thead>
            <tr>
              <th className={tableStyles.th}>Name</th>
              <th className={tableStyles.th}>Issued</th>
              <th className={tableStyles.th}>Status</th>
              <th className={tableStyles.th}>Total</th>
              <th className={tableStyles.th}>Link</th>
              <th className={`${tableStyles.th} ${tableStyles.thActions}`}>Actions</th>
            </tr>
          </thead>
          <tbody>
            {!loading && invoices.length === 0 ? (
              <tr>
                <td className={tableStyles.td} colSpan={6}>
                  No invoices yet for this business.
                </td>
              </tr>
            ) : null}
            {invoices.map((invoice) => (
              <tr key={invoice.id}>
                <td className={tableStyles.td}>
                  <div className={styles.itemTitle}>{invoice.name || `Invoice #${invoice.id}`}</div>
                  <div className={tableStyles.subText}>
                    {invoice.items?.length ?? 0} item{(invoice.items?.length ?? 0) === 1 ? '' : 's'}
                  </div>
                </td>
                <td className={tableStyles.td}>{formatDate(invoice.issuedAt)}</td>
                <td className={tableStyles.td}>
                  <button
                    type="button"
                    className={`${styles.statusChip} ${styles.statusChipBtn} ${statusClass(invoice.status)}`}
                    onClick={() => openStatusModal(invoice)}
                    title="Change status"
                    aria-label={`Change status (${statusLabel(invoice.status)})`}
                  >
                    {statusLabel(invoice.status)}
                  </button>
                </td>
                <td className={tableStyles.td}>{formatIrtPrice(invoice.total ?? 0)}</td>
                <td className={tableStyles.td}>
                  <div className={styles.linkRow}>
                    <a
                      className={styles.publicLink}
                      href={invoicePublicUrl(invoice)}
                      target="_blank"
                      rel="noreferrer"
                      title={invoicePublicUrl(invoice)}
                    >
                      {invoicePublicUrl(invoice).replace(/^https?:\/\//, '')}
                    </a>
                    <button
                      type="button"
                      className={styles.copyLinkBtn}
                      onClick={() => void copyPublicLink(invoice)}
                      title="Copy link"
                      aria-label="Copy invoice link"
                    >
                      <Copy size={14} />
                    </button>
                  </div>
                </td>
                <td className={`${tableStyles.td} ${tableStyles.tdActions}`}>
                  <div className={tableStyles.rowActions}>
                    <button
                      type="button"
                      className={tableStyles.controlBtn}
                      onClick={() => setDetailInvoice(invoice)}
                      title="View"
                      aria-label="View invoice"
                    >
                      <Eye size={16} />
                    </button>
                    <span
                      title={
                        canEditInvoice(invoice.status)
                          ? undefined
                          : 'Approved invoices cannot be edited'
                      }
                    >
                      <button
                        type="button"
                        className={tableStyles.controlBtn}
                        disabled={!canEditInvoice(invoice.status)}
                        onClick={() =>
                          navigate(`/businesses/${businessId}/invoices/${invoice.id}/edit`)
                        }
                        title={canEditInvoice(invoice.status) ? 'Edit' : undefined}
                        aria-label={
                          canEditInvoice(invoice.status)
                            ? 'Edit invoice'
                            : 'Edit invoice (disabled — approved)'
                        }
                      >
                        <Pencil size={16} />
                      </button>
                    </span>
                    <button
                      type="button"
                      className={`${tableStyles.controlBtn} ${tableStyles.controlBtnDanger}`}
                      onClick={() => setRemoveTarget(invoice)}
                      title="Remove"
                      aria-label="Remove invoice"
                    >
                      <Trash2 size={16} />
                    </button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {totalPages > 1 ? (
        <div className={tableStyles.pagination}>
          <div>
            Page {page} / {totalPages} · 20 per page · {total} total
          </div>
          <Pagination
            currentPage={page}
            totalPages={totalPages}
            onPageChange={setPage}
            disabled={loading}
            variant="inline"
          />
        </div>
      ) : null}

      <Modal
        open={!!detailInvoice}
        title={
          detailInvoice
            ? detailInvoice.name || `Invoice · ${formatDate(detailInvoice.issuedAt)}`
            : 'Invoice'
        }
        onClose={() => setDetailInvoice(null)}
        xl
      >
        {detailInvoice ? (
          <>
            <div className={styles.detailMeta}>
              <div>
                <span className={styles.detailLabel}>Status</span>
                <button
                  type="button"
                  className={`${styles.statusChip} ${styles.statusChipBtn} ${statusClass(detailInvoice.status)}`}
                  onClick={() => openStatusModal(detailInvoice)}
                  title="Change status"
                  aria-label={`Change status (${statusLabel(detailInvoice.status)})`}
                >
                  {statusLabel(detailInvoice.status)}
                </button>
              </div>
              <div>
                <span className={styles.detailLabel}>Total</span>
                <strong>{formatIrtPrice(detailInvoice.total ?? 0)}</strong>
              </div>
              <div>
                <span className={styles.detailLabel}>Public link</span>
                <div className={styles.linkRow}>
                  <a
                    className={styles.publicLink}
                    href={invoicePublicUrl(detailInvoice)}
                    target="_blank"
                    rel="noreferrer"
                  >
                    {invoicePublicUrl(detailInvoice).replace(/^https?:\/\//, '')}
                  </a>
                  <button
                    type="button"
                    className={styles.copyLinkBtn}
                    onClick={() => void copyPublicLink(detailInvoice)}
                    title="Copy link"
                    aria-label="Copy invoice link"
                  >
                    <Copy size={14} />
                  </button>
                </div>
              </div>
            </div>

            {detailInvoice.topText && !isEmptyRichText(detailInvoice.topText) ? (
              <div
                className={styles.detailNotes}
                dangerouslySetInnerHTML={{ __html: detailInvoice.topText }}
              />
            ) : null}
            {detailInvoice.notes ? (
              <p className={styles.detailNotes}>Notes: {detailInvoice.notes}</p>
            ) : null}

            <div className={styles.detailItems}>
              {(detailInvoice.items ?? []).map((item) => (
                <div key={item.id} className={styles.detailItem}>
                  <div className={styles.detailItemTop}>
                    <strong>{item.title}</strong>
                    <span>
                      {item.discountedPrice !== null && item.discountedPrice < item.price ? (
                        <>
                          <span className={styles.strike}>{formatIrtPrice(item.price)}</span>{' '}
                          {formatIrtPrice(item.discountedPrice)}
                        </>
                      ) : (
                        formatIrtPrice(item.price)
                      )}
                    </span>
                  </div>
                  <div className={styles.detailItemMeta}>
                    {item.duration ? <span>Duration: {item.duration}</span> : null}
                    {item.worktime ? <span>Worktime: {item.worktime}</span> : null}
                  </div>
                  {item.description ? (
                    <p className={styles.detailItemDesc}>{item.description}</p>
                  ) : null}
                </div>
              ))}
            </div>

            {(detailInvoice.keyPoints?.length ?? 0) > 0 ? (
              <div className={styles.blockSection}>
                <h4 className={styles.blockTitle}>Key points</h4>
                <ul className={styles.keyPointList}>
                  {detailInvoice.keyPoints!.map((kp) => (
                    <li key={kp.id}>{kp.text}</li>
                  ))}
                </ul>
              </div>
            ) : null}

            {(detailInvoice.accounts?.length ?? 0) > 0 ? (
              <div className={styles.blockSection}>
                <h4 className={styles.blockTitle}>Accounts</h4>
                <div className={styles.detailItems}>
                  {detailInvoice.accounts!.map((acc) => (
                    <div key={acc.id} className={styles.detailItem}>
                      <strong>{acc.bankName}</strong>
                      <div className={styles.detailItemMeta}>
                        {acc.accountHolderName ? <span>{acc.accountHolderName}</span> : null}
                        {acc.cardNumber ? <span>Card: {acc.cardNumber}</span> : null}
                        {acc.iban ? <span>IBAN: {acc.iban}</span> : null}
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            ) : null}
          </>
        ) : null}
      </Modal>

      <Modal
        open={!!statusTarget}
        title="Change invoice status"
        onClose={() => {
          if (!statusUpdating) setStatusTarget(null)
        }}
      >
        {statusTarget ? (
          <div
            className={styles.statusOptionList}
            role="listbox"
            aria-label="Invoice status"
          >
            {allowedStatusOptions(statusTarget.status).map((option) => {
              const selected = statusTarget.status === option
              const saving = statusUpdating === option
              return (
                <button
                  key={option}
                  type="button"
                  role="option"
                  aria-selected={selected}
                  className={`${styles.statusChip} ${styles.statusChipBtn} ${styles.statusOption} ${statusClass(option)} ${selected ? styles.statusOptionSelected : ''}`}
                  disabled={Boolean(statusUpdating)}
                  onClick={() => void handleStatusSelect(option)}
                >
                  {saving ? 'Saving…' : statusLabel(option)}
                </button>
              )
            })}
          </div>
        ) : null}
      </Modal>

      <ConfirmDeleteModal
        open={!!removeTarget}
        title="Remove invoice"
        message="Remove this invoice permanently? This cannot be undone."
        onCancel={() => setRemoveTarget(null)}
        onConfirm={() => void handleRemove()}
      />
    </main>
  )
}
