import { useEffect, useMemo, useState } from 'react'
import { MessageSquare, Pencil, Plus, RotateCcw, Search, Shield, Ticket, Trash2 } from 'lucide-react'
import { useLocale } from '@meshkee/dashboard-ui'
import { AddCustomerModal } from '../components/AddCustomerModal'
import { Breadcrumbs } from '../components/Breadcrumbs'
import { ChangeUserAccessModal } from '../components/ChangeUserAccessModal'
import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal'
import { EditCustomerModal } from '../components/EditCustomerModal'
import { PageTitle } from '../components/PageTitle'
import { Pagination } from '../components/Pagination'
import { ToggleSwitch } from '../components/ToggleSwitch'
import { Tooltip } from '../components/Tooltip'
import { useAuth } from '../context/AuthContext'
import { useToast } from '../context/ToastContext'
import { useT } from '../i18n/useT'
import type { BusinessMessageKey } from '../i18n/messages'
import { ApiError, isAbortError } from '../lib/api'
import { getActiveBusinessId } from '../lib/businessContext'
import { formatCellForDisplay } from '../lib/cellNumber'
import {
  listCustomers,
  removeCustomer,
  updateCustomerEnabled,
  type BusinessCustomerListItem,
  type CustomerAccessFilter,
  type CustomersListResponse,
} from '../services/customerService'
import { formatIrtPrice } from '../utils/irtPrice'
import { textLocaleAttrs } from '../utils/textLocale'
import filterStyles from '../components/ListFiltersPanel.module.css'
import pageStyles from '../components/PageContent.module.css'
import accessStyles from '../components/ChangeUserAccessModal.module.css'
import styles from './CustomersPage.module.css'

const PAGE_SIZE = 24
const COLUMN_COUNT = 7

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

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

function formatTransactionTotal(total: number | null | undefined) {
  if (total == null || total === 0) {
    return <span className={styles.subText}>—</span>
  }
  return formatIrtPrice(total)
}

function accessBadgeKey(user: BusinessCustomerListItem): BusinessMessageKey {
  if (user.isBusinessOwner) return 'customers.access.badge.owner'
  if (user.teamRole === 'admin') return 'customers.access.badge.admin'
  if (user.teamRole === 'editor') return 'customers.access.badge.editor'
  if (user.teamRole === 'viewer') return 'customers.access.badge.viewer'
  if (user.businessMemberId) return 'customers.access.badge.manager'
  return 'customers.access.customer'
}

function teamRoleMessageKey(teamRole: string): BusinessMessageKey {
  if (teamRole === 'admin') return 'customers.access.role.admin'
  if (teamRole === 'editor') return 'customers.access.role.editor'
  if (teamRole === 'viewer') return 'customers.access.role.viewer'
  return 'customers.access.badge.manager'
}

export function CustomersPage() {
  const t = useT()
  const { locale } = useLocale()
  const { user: authUser } = useAuth()
  const { showToast } = useToast()
  const [data, setData] = useState<CustomersListResponse | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState('')

  const [appliedFilters, setAppliedFilters] = useState<{
    name?: string
    cellNumber?: string
    access: CustomerAccessFilter
  }>({ access: 'all' })
  const [page, setPage] = useState(1)

  const [draftName, setDraftName] = useState('')
  const [draftCell, setDraftCell] = useState('')
  const [draftAccess, setDraftAccess] = useState<CustomerAccessFilter>('all')

  const [togglingId, setTogglingId] = useState<string | null>(null)
  const [editTarget, setEditTarget] = useState<BusinessCustomerListItem | null>(null)
  const [accessTarget, setAccessTarget] = useState<BusinessCustomerListItem | null>(null)
  const [createOpen, setCreateOpen] = useState(false)
  const [removeTarget, setRemoveTarget] = useState<BusinessCustomerListItem | null>(null)
  const [removing, setRemoving] = useState(false)

  const membership = useMemo(() => {
    const activeId = getActiveBusinessId()
    if (!authUser?.businesses.length) return undefined
    return (
      authUser.businesses.find((b) => String(b.id) === String(activeId)) ??
      authUser.businesses[0]
    )
  }, [authUser])
  const isSuperAdmin = Boolean(
    authUser?.isSuperAdmin || authUser?.roles.includes('super_admin'),
  )
  const canManageAccess =
    isSuperAdmin ||
    Boolean(membership?.isOwner) ||
    Boolean(membership?.permissions.includes('business.team.update'))

  function accessChangeDisabledReason(customer: BusinessCustomerListItem): string | null {
    if (customer.isBusinessOwner) return t('customers.access.ownerLocked')
    if (customer.teamRole === 'admin' && !isSuperAdmin) {
      return t('customers.access.adminLocked')
    }
    return null
  }

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

    async function load() {
      setLoading(true)
      setError('')
      try {
        const result = await listCustomers(
          {
            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('customers.error.load'))
      } finally {
        if (!controller.signal.aborted) setLoading(false)
      }
    }

    void load()

    return () => {
      controller.abort()
    }
  }, [page, appliedFilters.name, appliedFilters.cellNumber, appliedFilters.access, 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() {
    setPage(1)
    setAppliedFilters({
      access: draftAccess,
      ...(draftName.trim() ? { name: draftName.trim() } : {}),
      ...(draftCell.trim() ? { cellNumber: draftCell.trim() } : {}),
    })
  }

  function clearFilters() {
    setDraftName('')
    setDraftCell('')
    setDraftAccess('all')
    setPage(1)
    setAppliedFilters({ access: 'all' })
  }

  function handleAccessFilterChange(value: CustomerAccessFilter) {
    setDraftAccess(value)
    setPage(1)
    setAppliedFilters({
      access: value,
      ...(draftName.trim() ? { name: draftName.trim() } : {}),
      ...(draftCell.trim() ? { cellNumber: draftCell.trim() } : {}),
    })
  }

  async function handleToggleEnabled(customer: BusinessCustomerListItem, isEnabled: boolean) {
    setTogglingId(customer.id)
    setError('')
    try {
      await updateCustomerEnabled(customer.id, isEnabled)
      setData((prev) => {
        if (!prev) return prev
        return {
          ...prev,
          items: prev.items.map((item) =>
            item.id === customer.id ? { ...item, isEnabled } : item,
          ),
        }
      })
      showToast(
        isEnabled
          ? t('customers.toast.enabled', { name: displayName(customer) })
          : t('customers.toast.disabled', { name: displayName(customer) }),
        'success',
      )
    } catch (err) {
      setError(err instanceof ApiError ? err.message : t('customers.error.update'))
    } finally {
      setTogglingId(null)
    }
  }

  async function confirmRemove() {
    if (!removeTarget) return
    setRemoving(true)
    setError('')
    try {
      await removeCustomer(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('customers.toast.removed', { name: displayName(removeTarget) }), 'success')
      setRemoveTarget(null)
    } catch (err) {
      setError(err instanceof ApiError ? err.message : t('customers.error.remove'))
    } finally {
      setRemoving(false)
    }
  }

  function handleSendSms(customer: BusinessCustomerListItem) {
    showToast(
      t('customers.toast.smsSoon', { phone: formatCellForDisplay(customer.cellNumber) }),
      'info',
    )
  }

  function handleTickets(customer: BusinessCustomerListItem) {
    showToast(t('customers.toast.ticketsSoon', { name: displayName(customer) }), 'info')
  }

  function handleCustomerSaved(updated: BusinessCustomerListItem) {
    setData((prev) => {
      if (!prev) return prev
      return {
        ...prev,
        items: prev.items.map((item) => (item.id === updated.id ? updated : item)),
      }
    })
    showToast(t('customers.toast.updated', { name: displayName(updated) }), 'success')
  }

  function handleAccessSaved(updated: BusinessCustomerListItem) {
    setData((prev) => {
      if (!prev) return prev
      return {
        ...prev,
        items: prev.items.map((item) => (item.id === updated.id ? { ...item, ...updated } : item)),
      }
    })
    const roleLabel = updated.isBusinessOwner
      ? t('customers.access.badge.owner')
      : updated.teamRole
        ? t(teamRoleMessageKey(updated.teamRole))
        : t('customers.access.customer')
    showToast(t('customers.toast.accessUpdated', { role: roleLabel }), 'success')
  }

  function handleCustomerCreated(customer: BusinessCustomerListItem) {
    setPage(1)
    setData((prev) => {
      if (!prev) {
        return {
          items: [customer],
          total: 1,
          page: 1,
          pageSize: PAGE_SIZE,
        }
      }
      return {
        ...prev,
        total: prev.total + 1,
        page: 1,
        items: [customer, ...prev.items.filter((item) => item.id !== customer.id)].slice(
          0,
          PAGE_SIZE,
        ),
      }
    })
    showToast(t('customers.toast.added', { name: displayName(customer) }), 'success')
  }

  return (
    <main className={pageStyles.content}>
      <Breadcrumbs
        items={[
          { label: t('nav.home'), href: '/' },
          { label: t('customers.title') },
        ]}
      />

      <div className={pageStyles.pageHeader}>
        <PageTitle en="USERS">{t('customers.title')}</PageTitle>
      </div>

      <div className={filterStyles.filtersPanel}>
        <form className={filterStyles.filtersGrid} onSubmit={(e) => { e.preventDefault(); applyFilters() }}>
          <div className={filterStyles.filtersInputs}>
            <div className={`${filterStyles.field} ${filterStyles.fieldCol3}`}>
              <select
                id="filter-customer-access"
                value={draftAccess}
                onChange={(e) => handleAccessFilterChange(e.target.value as CustomerAccessFilter)}
                aria-label={t('customers.filter.access')}
                disabled={loading}
              >
                <option value="all">{t('customers.filter.access.all')}</option>
                <option value="customers">{t('customers.filter.access.customers')}</option>
                <option value="managers">{t('customers.filter.access.managers')}</option>
              </select>
            </div>
            <div className={`${filterStyles.field} ${filterStyles.fieldCol3}`}>
              <input
                id="filter-customer-name"
                value={draftName}
                onChange={(e) => setDraftName(e.target.value)}
                placeholder={t('customers.filter.name')}
                aria-label={t('customers.filter.name')}
              />
            </div>
            <div className={`${filterStyles.field} ${styles.filterCellNarrow}`}>
              <input
                id="filter-customer-cell"
                value={draftCell}
                onChange={(e) => setDraftCell(e.target.value)}
                placeholder={t('customers.filter.cell')}
                aria-label={t('customers.filter.cell')}
                autoComplete="off"
              />
            </div>
          </div>
          <div className={filterStyles.filterActions}>
            <button
              type="submit"
              className={`${filterStyles.iconActionBtn} ${filterStyles.iconActionBtnPrimary}`}
              disabled={loading}
              aria-label={t('customers.search')}
              title={t('customers.search')}
            >
              <Search size={18} />
            </button>
            <button
              type="button"
              className={`${filterStyles.iconActionBtn} ${filterStyles.iconActionBtnGhost}`}
              onClick={clearFilters}
              disabled={loading}
              aria-label={t('customers.clearFilters')}
              title={t('customers.clearFilters')}
            >
              <RotateCcw size={18} />
            </button>
          </div>
        </form>
      </div>

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

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

          <table
            className={`${styles.table}${locale === 'fa' ? ` ${styles.tableFa}` : ''}`}
            dir={locale === 'fa' ? 'rtl' : 'ltr'}
          >
            <colgroup>
              <col className={styles.colName} />
              <col className={styles.colRole} />
              <col className={styles.colCell} />
              <col className={styles.colOrders} />
              <col className={styles.colTransactions} />
              <col className={styles.colDate} />
              <col className={styles.colActions} />
            </colgroup>
            <thead>
              <tr>
                <th className={styles.th}>{t('customers.col.name')}</th>
                <th className={styles.th}>{t('customers.col.role')}</th>
                <th className={styles.th}>{t('customers.col.cell')}</th>
                <th className={styles.th}>{t('customers.col.orders')}</th>
                <th className={styles.th}>{t('customers.col.transactions')}</th>
                <th className={styles.th}>{t('customers.col.date')}</th>
                <th className={`${styles.th} ${styles.thActions}`}>{t('customers.col.actions')}</th>
              </tr>
            </thead>
            <tbody>
              {loading && (
                <tr>
                  <td className={styles.td} colSpan={COLUMN_COUNT}>
                    {t('customers.loading')}
                  </td>
                </tr>
              )}

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

              {!loading &&
                data?.items?.map((customer) => {
                  const name = displayName(customer)
                  const nameLocale = textLocaleAttrs(name)
                  const badgeKey = accessBadgeKey(customer)
                  const accessLocked = accessChangeDisabledReason(customer)
                  return (
                    <tr
                      key={customer.id}
                      className={!customer.isEnabled ? styles.inactiveRow : undefined}
                    >
                      <td className={styles.td}>
                        <div
                          className={[
                            styles.customerName,
                            nameLocale.className,
                            locale === 'fa' ? styles.nameAlignFa : '',
                          ]
                            .filter(Boolean)
                            .join(' ')}
                          lang={nameLocale.lang}
                          dir={nameLocale.dir}
                        >
                          {name}
                        </div>
                        {!customer.isEnabled && (
                          <div className={styles.statusDisabled}>{t('customers.disabled')}</div>
                        )}
                      </td>
                      <td className={styles.td}>
                        <span className={accessStyles.roleBadge}>{t(badgeKey)}</span>
                      </td>
                      <td className={styles.td}>{formatCellForDisplay(customer.cellNumber)}</td>
                      <td className={styles.td}>
                        {customer.orderCount == null || customer.orderCount === 0 ? (
                          <span className={styles.subText}>{t('customers.noOrders')}</span>
                        ) : (
                          customer.orderCount
                        )}
                      </td>
                      <td className={styles.td}>
                        {formatTransactionTotal(customer.totalTransactionsIrt)}
                      </td>
                      <td className={`${styles.td} ${styles.dateCell}`}>
                        {formatDate(customer.createdAt, locale)}
                      </td>
                      <td className={`${styles.td} ${styles.tdActions}`}>
                        <div className={styles.rowActions}>
                          <Tooltip
                            label={
                              customer.isEnabled
                                ? t('customers.disable')
                                : t('customers.enable')
                            }
                          >
                            <span className={styles.toggleInActions}>
                              <ToggleSwitch
                                checked={customer.isEnabled}
                                disabled={togglingId === customer.id || removing}
                                size="compact"
                                ariaLabel={
                                  customer.isEnabled
                                    ? t('customers.disableAria', { name })
                                    : t('customers.enableAria', { name })
                                }
                                onChange={(isEnabled) =>
                                  void handleToggleEnabled(customer, isEnabled)
                                }
                              />
                            </span>
                          </Tooltip>
                          {canManageAccess ? (
                            <Tooltip label={accessLocked ?? t('customers.access.change')}>
                              <button
                                type="button"
                                className={styles.actionBtn}
                                onClick={() => setAccessTarget(customer)}
                                aria-label={accessLocked ?? t('customers.access.change')}
                                disabled={Boolean(accessLocked) || removing}
                              >
                                <Shield size={15} />
                              </button>
                            </Tooltip>
                          ) : null}
                          <Tooltip label={t('customers.edit')}>
                            <button
                              type="button"
                              className={styles.actionBtn}
                              onClick={() => setEditTarget(customer)}
                              aria-label={t('customers.edit')}
                            >
                              <Pencil size={15} />
                            </button>
                          </Tooltip>
                          <Tooltip label={t('customers.sms')}>
                            <button
                              type="button"
                              className={styles.actionBtn}
                              onClick={() => handleSendSms(customer)}
                              aria-label={t('customers.sms')}
                            >
                              <MessageSquare size={15} />
                            </button>
                          </Tooltip>
                          <Tooltip label={t('customers.tickets')}>
                            <button
                              type="button"
                              className={styles.actionBtn}
                              onClick={() => handleTickets(customer)}
                              aria-label={t('customers.tickets')}
                            >
                              <Ticket size={15} />
                            </button>
                          </Tooltip>
                          <Tooltip label={t('customers.remove')}>
                            <button
                              type="button"
                              className={`${styles.actionBtn} ${styles.actionBtnDanger}`}
                              onClick={() => setRemoveTarget(customer)}
                              aria-label={t('customers.remove')}
                              disabled={removing}
                            >
                              <Trash2 size={15} />
                            </button>
                          </Tooltip>
                        </div>
                      </td>
                    </tr>
                  )
                })}
            </tbody>
          </table>

          <div className={styles.pagination}>
            <div>
              {t('customers.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>

      <AddCustomerModal
        open={createOpen}
        onClose={() => setCreateOpen(false)}
        onCreated={handleCustomerCreated}
      />

      <EditCustomerModal
        open={editTarget !== null}
        customer={editTarget}
        onClose={() => setEditTarget(null)}
        onSaved={handleCustomerSaved}
      />

      <ChangeUserAccessModal
        open={accessTarget !== null}
        user={accessTarget}
        canAssignAdmin={isSuperAdmin}
        onClose={() => setAccessTarget(null)}
        onSaved={handleAccessSaved}
      />

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

      <button
        type="button"
        className={styles.fab}
        onClick={() => setCreateOpen(true)}
        aria-label={t('customers.add')}
      >
        <Plus size={24} />
      </button>
    </main>
  )
}
