import {
  mdiAlertCircleOutline,
  mdiChartTimelineVariant,
  mdiClipboardCheckOutline,
  mdiClipboardTextClockOutline,
  mdiFileDownloadOutline,
  mdiFilterVariant,
  mdiPackageVariantClosedCheck,
  mdiPlus,
  mdiTable,
  mdiTruckDeliveryOutline,
} from '@mdi/js'
import Head from 'next/head'
import { uniqueId } from 'lodash'
import React, { ReactElement, useEffect, useMemo, useState } from 'react'
import CardBox from '../../components/CardBox'
import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import TableOrders from '../../components/Orders/TableOrders'
import BaseButton from '../../components/BaseButton'
import BaseIcon from '../../components/BaseIcon'
import axios from 'axios'
import Link from 'next/link'
import { useAppDispatch, useAppSelector } from '../../stores/hooks'
import CardBoxModal from '../../components/CardBoxModal'
import DragDropFilePicker from '../../components/DragDropFilePicker'
import { setRefetch, uploadCsv } from '../../stores/orders/ordersSlice'
import { hasPermission } from '../../helpers/userPermissions'

type OrderRow = {
  id: string
  order_number?: string
  po_number?: string
  order_status?: string
  order_total?: number | string
  ordered_at?: string
  requested_delivery_date?: string
  promised_delivery_date?: string
  account?: {
    account_name?: string
  }
  location?: {
    location_name?: string
    city?: string
    state?: string
  }
  buyer?: {
    firstName?: string
    lastName?: string
    email?: string
  }
}

const orderStatuses = ['submitted', 'approved', 'picking', 'shipped']

const currencyFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  maximumFractionDigits: 0,
})

const dateFormatter = new Intl.DateTimeFormat('en-US', {
  month: 'short',
  day: 'numeric',
})

const formatCurrency = (value?: number | string) => {
  const amount = Number(value || 0)

  if (!Number.isFinite(amount)) {
    return '$0'
  }

  return currencyFormatter.format(amount)
}

const formatDate = (value?: string) => {
  if (!value) {
    return 'Not scheduled'
  }

  return dateFormatter.format(new Date(value))
}

const formatStatus = (status?: string) => {
  if (!status) {
    return 'Unknown'
  }

  return status
    .split('_')
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join(' ')
}

const formatBuyer = (order: OrderRow) => {
  const name = [order.buyer?.firstName, order.buyer?.lastName]
    .filter(Boolean)
    .join(' ')

  return name || order.buyer?.email || 'Buyer not assigned'
}

const statusClasses = (status?: string) => {
  if (status === 'submitted') {
    return 'border-blue-200 bg-blue-50 text-blue-800'
  }

  if (status === 'approved') {
    return 'border-emerald-200 bg-emerald-50 text-emerald-800'
  }

  if (status === 'picking') {
    return 'border-amber-200 bg-amber-50 text-amber-800'
  }

  if (status === 'shipped') {
    return 'border-violet-200 bg-violet-50 text-violet-800'
  }

  if (status === 'delivered') {
    return 'border-slate-200 bg-slate-50 text-slate-700'
  }

  if (status === 'cancelled') {
    return 'border-rose-200 bg-rose-50 text-rose-800'
  }

  return 'border-slate-200 bg-white text-slate-700'
}

const isOpenOrder = (order: OrderRow) =>
  !['delivered', 'cancelled'].includes(order.order_status || '')

const isDueSoon = (order: OrderRow) => {
  if (!order.requested_delivery_date) {
    return false
  }

  const deliveryTime = new Date(order.requested_delivery_date).getTime()

  if (!Number.isFinite(deliveryTime)) {
    return false
  }

  const twoDaysFromNow = Date.now() + 2 * 24 * 60 * 60 * 1000
  return deliveryTime <= twoDaysFromNow
}

const StatusPill = ({ status }: { status?: string }) => (
  <span
    className={`inline-flex rounded-full border px-2.5 py-1 text-xs font-bold ${statusClasses(
      status,
    )}`}
  >
    {formatStatus(status)}
  </span>
)

const EmptyQueue = ({ label }: { label: string }) => (
  <div className='rounded-xl border border-dashed border-slate-300 bg-slate-50 p-4 text-sm font-medium text-slate-500 lg:col-span-2'>
    {label}
  </div>
)

const OrdersTablesPage = () => {
  const [filterItems, setFilterItems] = useState([])
  const [csvFile, setCsvFile] = useState<File | null>(null)
  const [isModalActive, setIsModalActive] = useState(false)
  const [ordersQueue, setOrdersQueue] = useState<OrderRow[]>([])
  const [ordersError, setOrdersError] = useState('')
  const [isOrdersLoading, setIsOrdersLoading] = useState(false)
  const { currentUser } = useAppSelector((state) => state.auth)
  const dispatch = useAppDispatch()

  const [filters] = useState([
    { label: 'Order number', title: 'order_number' },
    { label: 'PO number', title: 'po_number' },
    { label: 'Buyer notes', title: 'buyer_notes' },
    { label: 'Internal notes', title: 'internal_notes' },
    { label: 'Subtotal', title: 'subtotal', number: 'true' },
    { label: 'Tax total', title: 'tax_total', number: 'true' },
    { label: 'Shipping total', title: 'shipping_total', number: 'true' },
    { label: 'Order total', title: 'order_total', number: 'true' },
    { label: 'Ordered at', title: 'ordered_at', date: 'true' },
    {
      label: 'Requested delivery date',
      title: 'requested_delivery_date',
      date: 'true',
    },
    {
      label: 'Promised delivery date',
      title: 'promised_delivery_date',
      date: 'true',
    },
    { label: 'Account', title: 'account' },
    { label: 'Location', title: 'location' },
    { label: 'Buyer', title: 'buyer' },
    {
      label: 'Order status',
      title: 'order_status',
      type: 'enum',
      options: [
        'draft',
        'submitted',
        'approved',
        'picking',
        'shipped',
        'delivered',
        'cancelled',
      ],
    },
    {
      label: 'Payment terms',
      title: 'payment_terms',
      type: 'enum',
      options: ['net_15', 'net_30', 'net_45', 'prepaid'],
    },
  ])

  const hasCreatePermission =
    currentUser && hasPermission(currentUser, 'CREATE_ORDERS')
  const hasReadPermission =
    currentUser && hasPermission(currentUser, 'READ_ORDERS')

  useEffect(() => {
    if (!hasReadPermission) {
      return
    }

    const loadOrdersQueue = async () => {
      setIsOrdersLoading(true)
      setOrdersError('')

      try {
        const { data } = await axios.get('/orders', {
          params: {
            page: 0,
            limit: 24,
          },
        })
        setOrdersQueue(data.rows || [])
      } catch (error) {
        console.error('Failed to load purchase order operations queue', error)
        setOrdersError('Unable to load purchase order operations queue.')
      } finally {
        setIsOrdersLoading(false)
      }
    }

    void loadOrdersQueue()
  }, [hasReadPermission])

  const openOrders = useMemo(
    () => ordersQueue.filter(isOpenOrder),
    [ordersQueue],
  )
  const dueSoonOrders = useMemo(
    () => openOrders.filter(isDueSoon),
    [openOrders],
  )
  const orderValue = useMemo(
    () =>
      openOrders.reduce(
        (sum, order) => sum + Number(order.order_total || 0),
        0,
      ),
    [openOrders],
  )
  const statusCounts = useMemo(() => {
    const counts: Record<string, number> = {}

    orderStatuses.forEach((status) => {
      counts[status] = openOrders.filter(
        (order) => order.order_status === status,
      ).length
    })

    return counts
  }, [openOrders])
  const priorityOrders = useMemo(
    () =>
      [...openOrders]
        .sort((left, right) => {
          const leftTime = new Date(
            left.requested_delivery_date || left.ordered_at || '',
          ).getTime()
          const rightTime = new Date(
            right.requested_delivery_date || right.ordered_at || '',
          ).getTime()

          return (leftTime || 0) - (rightTime || 0)
        })
        .slice(0, 6),
    [openOrders],
  )

  const addFilter = () => {
    const newItem = {
      id: uniqueId(),
      fields: {
        filterValue: '',
        filterValueFrom: '',
        filterValueTo: '',
        selectedField: '',
      },
    }
    newItem.fields.selectedField = filters[0].title
    setFilterItems([...filterItems, newItem])
  }

  const getOrdersCSV = async () => {
    const response = await axios({
      url: '/orders?filetype=csv',
      method: 'GET',
      responseType: 'blob',
    })
    const type = response.headers['content-type']
    const blob = new Blob([response.data], { type: type })
    const link = document.createElement('a')
    link.href = window.URL.createObjectURL(blob)
    link.download = 'ordersCSV.csv'
    link.click()
  }

  const onModalConfirm = async () => {
    if (!csvFile) {
      setOrdersError('Choose a CSV file before confirming import.')
      return
    }

    await dispatch(uploadCsv(csvFile))
    dispatch(setRefetch(true))
    setCsvFile(null)
    setIsModalActive(false)
  }

  const onModalCancel = () => {
    setCsvFile(null)
    setIsModalActive(false)
  }

  return (
    <>
      <Head>
        <title>{getPageTitle('Purchase orders')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton
          icon={mdiChartTimelineVariant}
          title='Purchase orders'
          main
        >
          <div className='flex flex-wrap gap-2'>
            {hasCreatePermission && (
              <BaseButton
                href='/orders/orders-new'
                color='info'
                icon={mdiPlus}
                label='Create PO'
              />
            )}
            <BaseButton
              color='info'
              outline
              icon={mdiFilterVariant}
              label='Add filter'
              onClick={addFilter}
            />
          </div>
        </SectionTitleLineWithButton>

        {ordersError && (
          <div className='mb-5 rounded-2xl border border-rose-200 bg-rose-50 p-4 text-sm font-semibold text-rose-800'>
            {ordersError}
          </div>
        )}

        <section className='mb-6 overflow-hidden rounded-2xl border border-slate-200 bg-slate-950 text-white shadow-sm'>
          <div className='grid gap-6 p-6 xl:grid-cols-[minmax(0,1fr)_390px] xl:p-8'>
            <div>
              <p className='text-xs font-semibold uppercase tracking-[0.24em] text-emerald-300'>
                Supplier fulfillment queue
              </p>
              <h1 className='mt-4 max-w-4xl text-3xl font-semibold leading-tight lg:text-4xl'>
                Pick, invoice, and ship buyer purchase orders before the dock
                window closes.
              </h1>
              <p className='mt-4 max-w-3xl text-sm leading-7 text-slate-300'>
                Use this page as the operations view above the raw orders table:
                submitted orders, picking work, shipment handoff, and CSV
                controls stay in one place.
              </p>
              <div className='mt-6 flex flex-wrap gap-2'>
                {[
                  '3 PM cutoff',
                  'Contract pricing',
                  'Buyer portal orders',
                  'Fulfillment handoff',
                ].map((label) => (
                  <span
                    key={label}
                    className='rounded-full border border-white/10 bg-white/5 px-3 py-1 text-xs font-semibold text-slate-200'
                  >
                    {label}
                  </span>
                ))}
              </div>
            </div>
            <div className='grid gap-3 sm:grid-cols-2 xl:grid-cols-1'>
              <div className='rounded-xl border border-white/10 bg-white/5 p-4'>
                <p className='text-xs uppercase tracking-[0.18em] text-slate-400'>
                  Open value
                </p>
                <p className='mt-2 text-2xl font-semibold'>
                  {formatCurrency(orderValue)}
                </p>
              </div>
              <div className='rounded-xl border border-white/10 bg-white/5 p-4'>
                <p className='text-xs uppercase tracking-[0.18em] text-slate-400'>
                  Queue state
                </p>
                <p className='mt-2 text-2xl font-semibold'>
                  {isOrdersLoading ? 'Refreshing' : `${openOrders.length} open`}
                </p>
              </div>
            </div>
          </div>
        </section>

        <section className='mb-6 grid gap-4 sm:grid-cols-2 xl:grid-cols-5'>
          {[
            {
              label: 'Open POs',
              value: openOrders.length,
              detail: 'Active buyer orders',
              icon: mdiClipboardTextClockOutline,
            },
            {
              label: 'Due soon',
              value: dueSoonOrders.length,
              detail: 'Requested within 48h',
              icon: mdiAlertCircleOutline,
            },
            {
              label: 'Submitted',
              value: statusCounts.submitted || 0,
              detail: 'Needs approval',
              icon: mdiClipboardCheckOutline,
            },
            {
              label: 'Picking',
              value: statusCounts.picking || 0,
              detail: 'Warehouse work',
              icon: mdiPackageVariantClosedCheck,
            },
            {
              label: 'Shipped',
              value: statusCounts.shipped || 0,
              detail: 'Delivery handoff',
              icon: mdiTruckDeliveryOutline,
            },
          ].map((card) => (
            <div
              key={card.label}
              className='rounded-2xl border border-slate-200 bg-white p-4 shadow-sm'
            >
              <div className='flex items-start justify-between gap-3'>
                <div>
                  <p className='text-xs font-semibold uppercase tracking-[0.16em] text-slate-400'>
                    {card.label}
                  </p>
                  <p className='mt-3 text-3xl font-semibold text-slate-950'>
                    {card.value}
                  </p>
                </div>
                <span className='inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700'>
                  <BaseIcon path={card.icon} size='20' />
                </span>
              </div>
              <p className='mt-3 text-sm text-slate-500'>{card.detail}</p>
            </div>
          ))}
        </section>

        <section className='mb-6 grid gap-5 xl:grid-cols-[minmax(0,1.25fr)_minmax(340px,0.75fr)]'>
          <CardBox className='border border-slate-200 bg-white shadow-sm'>
            <div className='mb-5 flex flex-wrap items-start justify-between gap-3 border-b border-slate-100 pb-4'>
              <div>
                <p className='text-xs font-semibold uppercase tracking-[0.2em] text-emerald-700'>
                  Priority queue
                </p>
                <h2 className='mt-2 text-2xl font-semibold text-slate-950'>
                  Orders to work next
                </h2>
              </div>
              <BaseButton
                color='info'
                outline
                icon={mdiFileDownloadOutline}
                label='Export CSV'
                onClick={getOrdersCSV}
              />
            </div>
            <div className='grid gap-3 lg:grid-cols-2'>
              {priorityOrders.map((order) => (
                <Link
                  key={order.id}
                  href={`/orders/orders-view/?id=${order.id}`}
                  className='block rounded-2xl border border-slate-200 bg-slate-50 p-4 transition hover:border-emerald-200 hover:bg-emerald-50/70'
                >
                  <div className='flex items-start justify-between gap-3'>
                    <div className='min-w-0'>
                      <p className='truncate text-lg font-semibold text-slate-950'>
                        {order.order_number || 'Purchase order'}
                      </p>
                      <p className='mt-1 truncate text-sm text-slate-500'>
                        {order.account?.account_name || 'No buyer account'}
                      </p>
                    </div>
                    <StatusPill status={order.order_status} />
                  </div>
                  <div className='mt-4 grid gap-3 text-sm text-slate-600 sm:grid-cols-2'>
                    <div>
                      <p className='text-xs uppercase tracking-[0.14em] text-slate-400'>
                        PO
                      </p>
                      <p className='mt-1 font-semibold text-slate-900'>
                        {order.po_number || 'Pending'}
                      </p>
                    </div>
                    <div>
                      <p className='text-xs uppercase tracking-[0.14em] text-slate-400'>
                        Requested
                      </p>
                      <p className='mt-1 font-semibold text-slate-900'>
                        {formatDate(order.requested_delivery_date)}
                      </p>
                    </div>
                    <div>
                      <p className='text-xs uppercase tracking-[0.14em] text-slate-400'>
                        Buyer
                      </p>
                      <p className='mt-1 font-semibold text-slate-900'>
                        {formatBuyer(order)}
                      </p>
                    </div>
                    <div>
                      <p className='text-xs uppercase tracking-[0.14em] text-slate-400'>
                        Total
                      </p>
                      <p className='mt-1 font-semibold text-slate-900'>
                        {formatCurrency(order.order_total)}
                      </p>
                    </div>
                  </div>
                </Link>
              ))}
              {!priorityOrders.length && (
                <EmptyQueue label='No active purchase orders in the current queue.' />
              )}
            </div>
          </CardBox>

          <CardBox className='border border-slate-200 bg-white shadow-sm'>
            <div className='mb-5 border-b border-slate-100 pb-4'>
              <p className='text-xs font-semibold uppercase tracking-[0.2em] text-blue-700'>
                Workflow lanes
              </p>
              <h2 className='mt-2 text-2xl font-semibold text-slate-950'>
                Status breakdown
              </h2>
            </div>
            <div className='space-y-3'>
              {orderStatuses.map((status) => (
                <div
                  key={status}
                  className='rounded-xl border border-slate-200 bg-slate-50 p-4'
                >
                  <div className='flex items-center justify-between gap-3'>
                    <StatusPill status={status} />
                    <span className='text-2xl font-semibold text-slate-950'>
                      {statusCounts[status] || 0}
                    </span>
                  </div>
                  <p className='mt-2 text-sm text-slate-500'>
                    {status === 'submitted' &&
                      'Review buyer PO and approve fulfillment.'}
                    {status === 'approved' &&
                      'Ready for pick ticket and stock allocation.'}
                    {status === 'picking' &&
                      'Warehouse is preparing line items.'}
                    {status === 'shipped' && 'Delivery has left the dock.'}
                  </p>
                </div>
              ))}
            </div>
          </CardBox>
        </section>

        <CardBox
          className='mb-6 border border-slate-200 bg-white shadow-sm'
          cardBoxClassName='flex flex-wrap gap-3'
        >
          <BaseButton
            color='info'
            outline
            icon={mdiFilterVariant}
            label='Add filter'
            onClick={addFilter}
          />
          <BaseButton
            color='info'
            outline
            icon={mdiFileDownloadOutline}
            label='Export CSV'
            onClick={getOrdersCSV}
          />

          {hasCreatePermission && (
            <BaseButton
              color='info'
              outline
              label='Import CSV'
              onClick={() => setIsModalActive(true)}
            />
          )}

          <div className='md:inline-flex items-center ms-auto'>
            <div id='delete-rows-button'></div>
          </div>

          <div className='md:inline-flex items-center ms-auto'>
            <Link
              className='inline-flex items-center gap-2 rounded-xl border border-slate-200 px-3 py-2 text-sm font-semibold text-slate-700 hover:bg-slate-50'
              href='/orders/orders-table'
            >
              <BaseIcon path={mdiTable} size='16' />
              Table view
            </Link>
          </div>
        </CardBox>

        <TableOrders
          filterItems={filterItems}
          setFilterItems={setFilterItems}
          filters={filters}
          showGrid={false}
        />
      </SectionMain>
      <CardBoxModal
        title='Upload CSV'
        buttonColor='info'
        buttonLabel='Confirm'
        isActive={isModalActive}
        onConfirm={onModalConfirm}
        onCancel={onModalCancel}
      >
        <DragDropFilePicker
          file={csvFile}
          setFile={setCsvFile}
          formats='.csv'
        />
      </CardBoxModal>
    </>
  )
}

OrdersTablesPage.getLayout = function getLayout(page: ReactElement) {
  return (
    <LayoutAuthenticated permission='READ_ORDERS'>
      {page}
    </LayoutAuthenticated>
  )
}

export default OrdersTablesPage
