import { mdiChartTimelineVariant } from '@mdi/js'
import Head from 'next/head'
import { uniqueId } from 'lodash'
import React, { ReactElement, useEffect, useMemo, useState } from 'react'
import axios from 'axios'
import CardBox from '../../components/CardBox'
import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import TableAccounts from '../../components/Accounts/TableAccounts'
import BaseButton from '../../components/BaseButton'
import CardBoxModal from '../../components/CardBoxModal'
import DragDropFilePicker from '../../components/DragDropFilePicker'
import { getPageTitle } from '../../config'
import { useAppDispatch, useAppSelector } from '../../stores/hooks'
import { setRefetch, uploadCsv } from '../../stores/accounts/accountsSlice'
import { hasPermission } from '../../helpers/userPermissions'

type Person = {
  firstName?: string
  lastName?: string
  email?: string
}

type AccountRow = {
  id: string
  account_name?: string
  account_type?: string
  account_number?: string
  credit_status?: string
  credit_limit?: number | string
  is_tax_exempt?: boolean
  is_active?: boolean
  default_price_list?: {
    price_list_name?: string
    label?: string
  }
  assigned_sales_rep?: Person
  notes?: string
}

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

  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
    maximumFractionDigits: 0,
  }).format(amount)
}

const formatPerson = (person?: Person) => {
  if (!person) {
    return 'Unassigned'
  }

  const name = [person.firstName, person.lastName].filter(Boolean).join(' ')
  if (name) {
    return name
  }

  return person.email || 'Unassigned'
}

const formatPriceList = (row: AccountRow) => {
  return row.default_price_list?.price_list_name || row.default_price_list?.label || 'No default list'
}

const AccountsTablesPage = () => {
  const [filterItems, setFilterItems] = useState<any[]>([])
  const [csvFile, setCsvFile] = useState<File | null>(null)
  const [isModalActive, setIsModalActive] = useState(false)
  const [previewRows, setPreviewRows] = useState<AccountRow[]>([])
  const [pageError, setPageError] = useState('')
  const { currentUser } = useAppSelector((state) => state.auth)
  const dispatch = useAppDispatch()

  const [filters] = useState([
    { label: 'Account name', title: 'account_name' },
    { label: 'Account number', title: 'account_number' },
    { label: 'Tax exempt number', title: 'tax_exempt_number' },
    { label: 'Notes', title: 'notes' },
    { label: 'Credit limit', title: 'credit_limit', number: 'true' },
    { label: 'Default price list', title: 'default_price_list' },
    { label: 'Assigned sales rep', title: 'assigned_sales_rep' },
    {
      label: 'Account type',
      title: 'account_type',
      type: 'enum',
      options: ['restaurant', 'caterer', 'hotel', 'corporate', 'other'],
    },
    {
      label: 'Credit status',
      title: 'credit_status',
      type: 'enum',
      options: ['good', 'hold', 'delinquent'],
    },
  ])

  const hasCreatePermission = Boolean(currentUser && hasPermission(currentUser, 'CREATE_ACCOUNTS'))

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

    const loadPreviewRows = async () => {
      try {
        const { data } = await axios.get('/accounts', {
          params: {
            page: 0,
            limit: 12,
          },
        })
        const rows = Array.isArray(data?.rows) ? data.rows : data
        setPreviewRows(Array.isArray(rows) ? rows : [])
        setPageError('')
      } catch (error) {
        console.error('Failed to load buyer account workspace', error)
        setPageError('Unable to load buyer accounts. Check API access or retry the page.')
      }
    }

    loadPreviewRows()
  }, [currentUser])

  const stats = useMemo(() => {
    const activeCount = previewRows.filter((row) => row.is_active !== false).length
    const holdCount = previewRows.filter((row) => row.credit_status === 'hold').length
    const creditLimit = previewRows.reduce((total, row) => total + Number(row.credit_limit || 0), 0)

    return {
      activeCount,
      holdCount,
      creditLimit,
    }
  }, [previewRows])

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

  const getAccountsCSV = async () => {
    try {
      const response = await axios({
        url: '/accounts?filetype=csv',
        method: 'GET',
        responseType: 'blob',
      })
      const type = response.headers['content-type']
      const blob = new Blob([response.data], { type })
      const link = document.createElement('a')
      link.href = window.URL.createObjectURL(blob)
      link.download = 'buyer-accounts.csv'
      link.click()
      setPageError('')
    } catch (error) {
      console.error('Failed to export buyer accounts CSV', error)
      setPageError('CSV export failed. Check the accounts API and try again.')
    }
  }

  const onModalConfirm = async () => {
    if (!csvFile) {
      setPageError('Choose a CSV file before importing buyer accounts.')
      return
    }

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

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

  return (
    <>
      <Head>
        <title>{getPageTitle('Buyer account workspace')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton
          icon={mdiChartTimelineVariant}
          title='Buyer account workspace'
          main
        >
          {''}
        </SectionTitleLineWithButton>

        <div className='mb-6 grid gap-6 lg:grid-cols-[1.2fr_0.8fr]'>
          <CardBox>
            <p className='text-xs font-bold uppercase tracking-[0.22em] text-emerald-600'>
              Customer control center
            </p>
            <h1 className='mt-3 text-3xl font-bold text-slate-950 dark:text-white'>
              Manage restaurants, hotels, caterers, and corporate buyers
            </h1>
            <p className='mt-3 max-w-3xl text-sm leading-6 text-slate-600 dark:text-slate-300'>
              Buyer accounts define contract pricing, credit status, tax handling, sales rep
              ownership, and the access rules buyers receive when they sign in to reorder.
            </p>
          </CardBox>

          <CardBox cardBoxClassName='space-y-4'>
            <div className='flex items-center justify-between gap-4'>
              <span className='text-sm text-slate-500 dark:text-slate-400'>Active buyers</span>
              <span className='text-2xl font-bold text-slate-950 dark:text-white'>{stats.activeCount}</span>
            </div>
            <div className='flex items-center justify-between gap-4'>
              <span className='text-sm text-slate-500 dark:text-slate-400'>Credit on hold</span>
              <span className='text-2xl font-bold text-slate-950 dark:text-white'>{stats.holdCount}</span>
            </div>
            <div className='rounded border border-slate-200 bg-slate-50 p-3 dark:border-slate-700 dark:bg-slate-800'>
              <p className='text-xs font-bold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400'>
                Managed credit
              </p>
              <p className='mt-1 text-sm font-semibold text-slate-900 dark:text-slate-100'>
                {formatCurrency(stats.creditLimit)} across visible accounts
              </p>
            </div>
          </CardBox>
        </div>

        {pageError && (
          <div className='mb-6 rounded border border-red-200 bg-red-50 p-4 text-sm font-semibold text-red-800 dark:border-red-800 dark:bg-red-950/30 dark:text-red-200'>
            {pageError}
          </div>
        )}

        <div className='mb-6 grid gap-4 md:grid-cols-3'>
          {previewRows.slice(0, 3).map((row) => (
            <div
              key={row.id}
              className='rounded border border-slate-200 bg-white p-5 dark:border-slate-700 dark:bg-slate-900'
            >
              <div className='flex items-start justify-between gap-3'>
                <div>
                  <p className='text-xs font-bold uppercase tracking-[0.18em] text-emerald-600'>
                    {row.account_type || 'buyer'}
                  </p>
                  <h2 className='mt-2 text-lg font-bold text-slate-950 dark:text-white'>
                    {row.account_name || 'Untitled account'}
                  </h2>
                </div>
                <span className='rounded-full bg-emerald-50 px-3 py-1 text-xs font-bold text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300'>
                  {row.credit_status || 'good'}
                </span>
              </div>
              <div className='mt-5 space-y-3 text-sm'>
                <div className='flex justify-between gap-4'>
                  <span className='text-slate-500 dark:text-slate-400'>Price list</span>
                  <span className='font-semibold text-slate-950 dark:text-white'>{formatPriceList(row)}</span>
                </div>
                <div className='flex justify-between gap-4'>
                  <span className='text-slate-500 dark:text-slate-400'>Sales rep</span>
                  <span className='font-semibold text-slate-950 dark:text-white'>
                    {formatPerson(row.assigned_sales_rep)}
                  </span>
                </div>
                <div className='flex justify-between gap-4'>
                  <span className='text-slate-500 dark:text-slate-400'>Credit limit</span>
                  <span className='font-semibold text-slate-950 dark:text-white'>
                    {formatCurrency(row.credit_limit)}
                  </span>
                </div>
              </div>
            </div>
          ))}
        </div>

        <CardBox className='mb-6' cardBoxClassName='flex flex-wrap items-center gap-3'>
          {hasCreatePermission && (
            <BaseButton href='/accounts/accounts-new' color='info' label='Add buyer account' />
          )}
          <BaseButton color='info' outline label='Add filter' onClick={addFilter} />
          <BaseButton color='info' outline label='Export CSV' onClick={getAccountsCSV} />
          {hasCreatePermission && (
            <BaseButton color='info' outline label='Import CSV' onClick={() => setIsModalActive(true)} />
          )}
          <div className='md:ml-auto' id='delete-rows-button'></div>
        </CardBox>

        <CardBox className='mb-6' hasTable>
          <TableAccounts
            filterItems={filterItems}
            setFilterItems={setFilterItems}
            filters={filters}
            showGrid={false}
          />
        </CardBox>
      </SectionMain>

      <CardBoxModal
        title='Import buyer accounts CSV'
        buttonColor='info'
        buttonLabel='Confirm'
        isActive={isModalActive}
        onConfirm={onModalConfirm}
        onCancel={onModalCancel}
      >
        <DragDropFilePicker file={csvFile} setFile={setCsvFile} formats='.csv' />
      </CardBoxModal>
    </>
  )
}

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

export default AccountsTablesPage
