import { useEffect, useMemo, useState } from 'react'
import { CreditCard, Eye, RotateCcw, Search, Trash2 } from 'lucide-react'
import { useLocale } from '@meshkee/dashboard-ui'
import { Breadcrumbs } from '../components/Breadcrumbs'
import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal'
import { OrderItemsModal } from '../components/OrderItemsModal'
import { OrderStepModal } from '../components/OrderStepModal'
import { OrderTransactionsModal } from '../components/OrderTransactionsModal'
import { Pagination } from '../components/Pagination'
import { Tooltip } from '../components/Tooltip'
import { useToast } from '../context/ToastContext'
import { useT } from '../i18n/useT'
import { ApiError, isAbortError } from '../lib/api'
import { formatCellForDisplay } from '../lib/cellNumber'
import {
  listOrders,
  removeOrder,
  type Order,
  type OrdersListResponse,
  type OrderSource,
} from '../services/orderService'
import {
  getSettings,
  DEFAULT_ORDER_PROCESS_STEPS,
  type OrderProcessStep,
} from '../services/settingsService'
import { formatIrtInput, formatIrtPrice, parseIrtInput } from '../utils/irtPrice'
import { stepBadgeStyle } from '../utils/stepColors'
import filterStyles from '../components/ListFiltersPanel.module.css'
import pageStyles from '../components/PageContent.module.css'
import styles from './OrdersPage.module.css'

const PAGE_SIZE = 24
const COLUMN_COUNT = 8

interface AppliedFilters {
  orderNumber?: string
  customerQuery?: string
  dateFrom?: string
  dateTo?: string
  minTotal?: number
  maxTotal?: number
}

function displayName(order: Order) {
  const name = [order.customer.firstName, order.customer.lastName].filter(Boolean).join(' ').trim()
  return name || '—'
}

function formatDateTime(value: string, locale: 'en' | 'fa') {
  const d = new Date(value)
  if (Number.isNaN(d.getTime())) return { date: value, time: '' }
  const intlLocale = locale === 'fa' ? 'fa-IR' : 'en-US'
  return {
    date: d.toLocaleDateString(intlLocale, { year: 'numeric', month: 'short', day: '2-digit' }),
    time: d.toLocaleTimeString(intlLocale, { hour: '2-digit', minute: '2-digit' }),
  }
}

function totalItemQuantity(order: Order) {
  return order.items.reduce((sum, item) => sum + item.quantity, 0)
}

function defaultFaForLabel(label: string | null | undefined) {
  const trimmed = label?.trim()
  if (!trimmed) return undefined
  return DEFAULT_ORDER_PROCESS_STEPS.find(
    (step) => step.label.toLowerCase() === trimmed.toLowerCase(),
  )?.labelFa
}

function stepLabel(
  steps: OrderProcessStep[],
  processStepId: string,
  processStepLabel?: string | null,
  processStepLabelFa?: string | null,
  locale: 'en' | 'fa' = 'en',
) {
  const step =
    steps.find((item) => item.id === processStepId) ??
    DEFAULT_ORDER_PROCESS_STEPS.find((item) => item.id === processStepId)

  if (locale === 'fa') {
    let fa = processStepLabelFa?.trim() || step?.labelFa?.trim()

    if (fa && processStepLabel?.trim() && fa === processStepLabel.trim()) {
      fa = undefined
    }

    fa = fa || defaultFaForLabel(processStepLabel) || defaultFaForLabel(step?.label)

    if (fa) return fa
  }

  if (processStepLabel?.trim()) return processStepLabel.trim()
  return step?.label ?? processStepId
}

function sourceClass(source: OrderSource) {
  switch (source) {
    case 'admin':
      return styles.sourceOperator
    case 'app':
      return styles.sourceApplication
    case 'website':
    default:
      return styles.sourceWebsite
  }
}

function stepColor(
  steps: OrderProcessStep[],
  processStepId: string,
  processStepColor?: string | null,
) {
  if (processStepColor?.trim()) return processStepColor.trim()
  const index = steps.findIndex((step) => step.id === processStepId)
  const step = index >= 0 ? steps[index] : steps[0]
  if (step?.color) return step.color

  if (typeof document !== 'undefined') {
    const themed = getComputedStyle(document.documentElement)
      .getPropertyValue('--primary')
      .trim()
    if (themed) return themed
  }

  return '#3b82f6'
}

export function OrdersPage() {
  const t = useT()
  const { locale } = useLocale()
  const { showToast } = useToast()
  const [data, setData] = useState<OrdersListResponse | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState('')

  const [appliedFilters, setAppliedFilters] = useState<AppliedFilters>({})
  const [page, setPage] = useState(1)

  const [draftOrderId, setDraftOrderId] = useState('')
  const [draftCustomer, setDraftCustomer] = useState('')
  const [draftDateFrom, setDraftDateFrom] = useState('')
  const [draftDateTo, setDraftDateTo] = useState('')
  const [draftMinCost, setDraftMinCost] = useState('')
  const [draftMaxCost, setDraftMaxCost] = useState('')

  const [viewOrder, setViewOrder] = useState<Order | null>(null)
  const [transactionsOrder, setTransactionsOrder] = useState<Order | null>(null)
  const [stepOrder, setStepOrder] = useState<Order | null>(null)
  const [processSteps, setProcessSteps] = useState<OrderProcessStep[]>(DEFAULT_ORDER_PROCESS_STEPS)
  const [removeTarget, setRemoveTarget] = useState<Order | null>(null)
  const [removing, setRemoving] = useState(false)

  function sourceLabel(source: OrderSource) {
    switch (source) {
      case 'admin':
        return t('orders.source.operator')
      case 'app':
        return t('orders.source.app')
      case 'website':
      default:
        return t('orders.source.website')
    }
  }

  useEffect(() => {
    const controller = new AbortController()

    async function loadSteps() {
      try {
        const data = await getSettings(controller.signal)
        setProcessSteps(data.settings.store.orderProcessSteps)
      } catch (err) {
        if (isAbortError(err) || controller.signal.aborted) return
      }
    }

    void loadSteps()
    return () => controller.abort()
  }, [])

  useEffect(() => {
    const controller = new AbortController()

    async function load() {
      setLoading(true)
      setError('')
      try {
        const result = await listOrders(
          {
            page,
            pageSize: PAGE_SIZE,
            ...appliedFilters,
          },
          controller.signal,
        )
        if (controller.signal.aborted) return
        setData(result)
      } catch (err) {
        if (isAbortError(err) || controller.signal.aborted) return
        setError(err instanceof ApiError ? err.message : t('orders.error.load'))
      } finally {
        if (!controller.signal.aborted) setLoading(false)
      }
    }

    void load()

    return () => {
      controller.abort()
    }
  }, [
    page,
    appliedFilters.orderNumber,
    appliedFilters.customerQuery,
    appliedFilters.dateFrom,
    appliedFilters.dateTo,
    appliedFilters.minTotal,
    appliedFilters.maxTotal,
    t,
  ])

  const totalPages = useMemo(() => {
    const total = data?.total ?? 0
    return Math.max(1, Math.ceil(total / PAGE_SIZE))
  }, [data?.total])

  const showingFrom = useMemo(() => {
    if (!data || data.total === 0) return 0
    return (page - 1) * PAGE_SIZE + 1
  }, [data, page])

  const showingTo = useMemo(() => {
    if (!data) return 0
    return Math.min(data.total, page * PAGE_SIZE)
  }, [data, page])

  function applyFilters() {
    const minTotal = parseIrtInput(draftMinCost)
    const maxTotal = parseIrtInput(draftMaxCost)

    if (minTotal !== null && maxTotal !== null && minTotal > maxTotal) {
      setError(t('orders.error.minMax'))
      return
    }

    setPage(1)
    setAppliedFilters({
      ...(draftOrderId.trim() ? { orderNumber: draftOrderId.trim() } : {}),
      ...(draftCustomer.trim() ? { customerQuery: draftCustomer.trim() } : {}),
      ...(draftDateFrom ? { dateFrom: draftDateFrom } : {}),
      ...(draftDateTo ? { dateTo: draftDateTo } : {}),
      ...(minTotal !== null ? { minTotal } : {}),
      ...(maxTotal !== null ? { maxTotal } : {}),
    })
  }

  function clearFilters() {
    setDraftOrderId('')
    setDraftCustomer('')
    setDraftDateFrom('')
    setDraftDateTo('')
    setDraftMinCost('')
    setDraftMaxCost('')
    setPage(1)
    setAppliedFilters({})
    setError('')
  }

  function handleStepSaved(updated: Order) {
    setData((prev) => {
      if (!prev) return prev
      return {
        ...prev,
        items: prev.items.map((item) => (item.id === updated.id ? updated : item)),
      }
    })
  }

  async function confirmRemove() {
    if (!removeTarget) return
    setRemoving(true)
    setError('')
    try {
      await removeOrder(removeTarget.id)
      setData((prev) => {
        if (!prev) return prev
        return {
          ...prev,
          total: Math.max(0, prev.total - 1),
          items: prev.items.filter((item) => item.id !== removeTarget.id),
        }
      })
      showToast(t('orders.removed', { orderNumber: removeTarget.orderNumber }), 'success')
      setRemoveTarget(null)
    } catch (err) {
      setError(err instanceof ApiError ? err.message : t('orders.error.remove'))
    } finally {
      setRemoving(false)
    }
  }

  return (
    <main className={pageStyles.content}>
      <Breadcrumbs
        items={[
          { label: 'Home', href: '/' },
          { label: 'Store', href: '/store' },
          { label: 'Orders' },
        ]}
      />

      <div className={pageStyles.pageHeader}>
        <div>
          <h2 className={pageStyles.pageTitle}>{t('orders.title')}</h2>
          <p className={pageStyles.pageSubtitle}>{t('orders.subtitle')}</p>
        </div>
      </div>

      <div className={filterStyles.filtersPanel}>
        <div className={filterStyles.filtersTitle}>{t('orders.filters')}</div>
        <div className={filterStyles.filtersGrid}>
          <div className={styles.ordersFiltersRow}>
            <div className={`${filterStyles.field} ${styles.filterOrderId}`}>
              <input
                id="filter-order-id"
                value={draftOrderId}
                onChange={(e) => setDraftOrderId(e.target.value)}
                placeholder={t('orders.filter.orderId')}
                aria-label={t('orders.filter.orderId')}
              />
            </div>
            <div className={`${filterStyles.field} ${styles.filterCustomer}`}>
              <input
                id="filter-order-customer"
                value={draftCustomer}
                onChange={(e) => setDraftCustomer(e.target.value)}
                placeholder={t('orders.filter.customer')}
                aria-label={t('orders.filter.customer')}
                autoComplete="off"
              />
            </div>
            <div className={`${filterStyles.field} ${styles.filterDate}`}>
              <input
                id="filter-order-date-from"
                type="date"
                value={draftDateFrom}
                onChange={(e) => setDraftDateFrom(e.target.value)}
                aria-label={t('orders.filter.dateFrom')}
                title={t('orders.filter.dateFrom')}
              />
            </div>
            <div className={`${filterStyles.field} ${styles.filterDate}`}>
              <input
                id="filter-order-date-to"
                type="date"
                value={draftDateTo}
                onChange={(e) => setDraftDateTo(e.target.value)}
                aria-label={t('orders.filter.dateTo')}
                title={t('orders.filter.dateTo')}
              />
            </div>
            <div className={`${filterStyles.field} ${styles.filterCost}`}>
              <input
                id="filter-order-min-cost"
                type="text"
                inputMode="numeric"
                value={draftMinCost}
                onChange={(e) => setDraftMinCost(formatIrtInput(e.target.value))}
                placeholder={t('orders.filter.minCost')}
                aria-label={t('orders.filter.minCost')}
                autoComplete="off"
              />
            </div>
            <div className={`${filterStyles.field} ${styles.filterCost}`}>
              <input
                id="filter-order-max-cost"
                type="text"
                inputMode="numeric"
                value={draftMaxCost}
                onChange={(e) => setDraftMaxCost(formatIrtInput(e.target.value))}
                placeholder={t('orders.filter.maxCost')}
                aria-label={t('orders.filter.maxCost')}
                autoComplete="off"
              />
            </div>
          </div>
          <div className={filterStyles.filterActions}>
            <button
              type="button"
              className={`${filterStyles.iconActionBtn} ${filterStyles.iconActionBtnPrimary}`}
              onClick={applyFilters}
              disabled={loading}
              aria-label={t('orders.search')}
              title={t('orders.search')}
            >
              <Search size={18} />
            </button>
            <button
              type="button"
              className={`${filterStyles.iconActionBtn} ${filterStyles.iconActionBtnGhost}`}
              onClick={clearFilters}
              disabled={loading}
              aria-label={t('orders.clearFilters')}
              title={t('orders.clearFilters')}
            >
              <RotateCcw size={18} />
            </button>
          </div>
        </div>
      </div>

      <div className={styles.tablePanel}>
        <div className={styles.tableWrap}>
          <div className={styles.tableHeader}>
            <div className={styles.tableHeaderTitle}>{t('orders.listTitle')}</div>
            <div className={styles.meta}>
              {data ? (
                data.total > 0 ? (
                  t('orders.showing', {
                    from: showingFrom,
                    to: showingTo,
                    total: data.total,
                  })
                ) : (
                  t('orders.none')
                )
              ) : (
                ' '
              )}
            </div>
          </div>

          {error && <div className={styles.errorBanner}>{error}</div>}

          <table className={styles.table} dir={locale === 'fa' ? 'rtl' : 'ltr'}>
            <colgroup>
              <col className={styles.colOrderId} />
              <col className={styles.colCustomer} />
              <col className={styles.colItems} />
              <col className={styles.colTotal} />
              <col className={styles.colDate} />
              <col className={styles.colStep} />
              <col className={styles.colSource} />
              <col className={styles.colActions} />
            </colgroup>
            <thead>
              <tr>
                <th className={styles.th}>{t('orders.col.orderId')}</th>
                <th className={styles.th}>{t('orders.col.customer')}</th>
                <th className={styles.th}>{t('orders.col.items')}</th>
                <th className={styles.th}>{t('orders.col.total')}</th>
                <th className={styles.th}>{t('orders.col.date')}</th>
                <th className={styles.th}>{t('orders.col.step')}</th>
                <th className={styles.th}>{t('orders.col.source')}</th>
                <th className={`${styles.th} ${styles.thActions}`}>{t('orders.col.actions')}</th>
              </tr>
            </thead>
            <tbody>
              {loading && (
                <tr>
                  <td className={styles.td} colSpan={COLUMN_COUNT}>
                    {t('orders.loading')}
                  </td>
                </tr>
              )}

              {!loading && data?.items?.length === 0 && (
                <tr>
                  <td className={styles.td} colSpan={COLUMN_COUNT}>
                    {t('orders.empty')}
                  </td>
                </tr>
              )}

              {!loading &&
                data?.items?.map((order) => {
                  const { date, time } = formatDateTime(order.createdAt, locale)
                  const itemQty = totalItemQuantity(order)
                  const currentStepLabel = stepLabel(
                    processSteps,
                    order.processStepId ?? processSteps[0]?.id ?? 'processing',
                    order.processStepLabel,
                    order.processStepLabelFa,
                    locale,
                  )

                  return (
                    <tr key={order.id}>
                      <td className={styles.td}>
                        <div className={styles.orderNumber}>{order.orderNumber}</div>
                      </td>
                      <td className={styles.td}>
                        <div className={styles.customerName}>{displayName(order)}</div>
                        <div className={styles.customerCell}>
                          {formatCellForDisplay(order.customer.cellNumber)}
                        </div>
                      </td>
                      <td className={styles.td}>
                        {itemQty > 0 ? itemQty : <span className={styles.subText}>0</span>}
                      </td>
                      <td className={styles.td}>{formatIrtPrice(order.total)}</td>
                      <td className={`${styles.td} ${styles.dateCell}`}>
                        <div className={styles.dateTime}>{date}</div>
                        {time && <div className={styles.dateTimeSub}>{time}</div>}
                      </td>
                      <td className={styles.td}>
                        <button
                          type="button"
                          className={styles.stepBadge}
                          style={stepBadgeStyle(
                            stepColor(
                              processSteps,
                              order.processStepId ?? processSteps[0]?.id ?? 'processing',
                              order.processStepColor,
                            ),
                          )}
                          onClick={() => setStepOrder(order)}
                          aria-label={t('orders.changeStep', { step: currentStepLabel })}
                        >
                          {currentStepLabel}
                        </button>
                      </td>
                      <td className={styles.td}>
                        <span className={`${styles.sourceBadge} ${sourceClass(order.source)}`}>
                          {sourceLabel(order.source)}
                        </span>
                      </td>
                      <td className={`${styles.td} ${styles.tdActions}`}>
                        <div className={styles.rowActions}>
                          <Tooltip label={t('orders.viewItems')}>
                            <button
                              type="button"
                              className={styles.actionBtn}
                              onClick={() => setViewOrder(order)}
                              aria-label={t('orders.viewItems')}
                            >
                              <Eye size={15} />
                            </button>
                          </Tooltip>
                          <Tooltip label={t('orders.transactions')}>
                            <button
                              type="button"
                              className={styles.actionBtn}
                              onClick={() => setTransactionsOrder(order)}
                              aria-label={t('orders.transactions')}
                            >
                              <CreditCard size={15} />
                            </button>
                          </Tooltip>
                          <Tooltip label={t('orders.remove')}>
                            <button
                              type="button"
                              className={`${styles.actionBtn} ${styles.actionBtnDanger}`}
                              onClick={() => setRemoveTarget(order)}
                              aria-label={t('orders.remove')}
                              disabled={removing}
                            >
                              <Trash2 size={15} />
                            </button>
                          </Tooltip>
                        </div>
                      </td>
                    </tr>
                  )
                })}
            </tbody>
          </table>

          <div className={styles.pagination}>
            <div>
              {t('orders.pageMeta', {
                page,
                totalPages,
                pageSize: PAGE_SIZE,
                total: data?.total ?? 0,
              })}
            </div>
            <Pagination
              currentPage={page}
              totalPages={totalPages}
              onPageChange={setPage}
              disabled={loading}
              variant="inline"
            />
          </div>
        </div>
      </div>

      <OrderItemsModal
        open={viewOrder !== null}
        order={viewOrder}
        onClose={() => setViewOrder(null)}
      />

      <OrderTransactionsModal
        open={transactionsOrder !== null}
        order={transactionsOrder}
        onClose={() => setTransactionsOrder(null)}
      />

      <OrderStepModal
        open={stepOrder !== null}
        order={stepOrder}
        steps={processSteps}
        onClose={() => setStepOrder(null)}
        onSaved={handleStepSaved}
      />

      <ConfirmDeleteModal
        open={removeTarget !== null}
        title={t('orders.deleteTitle')}
        message={
          removeTarget
            ? t('orders.deleteMessage', { orderNumber: removeTarget.orderNumber })
            : ''
        }
        onCancel={() => setRemoveTarget(null)}
        onConfirm={() => void confirmRemove()}
      />
    </main>
  )
}
