import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { usePOSStore } from '@/stores/pos.store'
import { posMutations, posKeys, drawerReportOptions, type DrawerSession } from '@/api/pos'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Separator } from '@/components/ui/separator'
import { Badge } from '@/components/ui/badge'
import { ArrowDownToLine, ArrowUpFromLine } from 'lucide-react'
import { toast } from 'sonner'
import { ManagerOverrideDialog, requiresOverride } from './pos-manager-override'

interface POSDrawerDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  drawer: DrawerSession | null
}

export function POSDrawerDialog({ open, onOpenChange, drawer }: POSDrawerDialogProps) {
  const queryClient = useQueryClient()
  const { locationId, registerId, setDrawerSession } = usePOSStore()
  const isOpen = drawer?.status === 'open'

  const [openingBalance, setOpeningBalance] = useState('200')
  const [closingBalance, setClosingBalance] = useState('')
  const [notes, setNotes] = useState('')
  const [adjustView, setAdjustView] = useState<'cash_in' | 'cash_out' | null>(null)
  const [adjAmount, setAdjAmount] = useState('')
  const [adjReason, setAdjReason] = useState('')
  const [overrideOpen, setOverrideOpen] = useState(false)
  const [pendingAdjustView, setPendingAdjustView] = useState<'cash_in' | 'cash_out' | null>(null)
  const [showZReport, setShowZReport] = useState(false)
  const [closedDrawerId, setClosedDrawerId] = useState<string | null>(null)
  const [showXReport, setShowXReport] = useState(false)

  // Z Report data (after close)
  const { data: reportData } = useQuery(drawerReportOptions(closedDrawerId))

  // X Report data (live, for open drawer)
  const { data: xReportData } = useQuery(drawerReportOptions(showXReport ? drawer?.id ?? null : null))

  // Fetch adjustments for open drawer
  const { data: adjData } = useQuery({
    queryKey: posKeys.drawerAdjustments(drawer?.id ?? ''),
    queryFn: () => posMutations.getAdjustments(drawer!.id),
    enabled: !!drawer?.id && isOpen,
  })
  const adjustments = adjData?.data ?? []

  const openMutation = useMutation({
    mutationFn: () =>
      posMutations.openDrawer({
        locationId: locationId ?? undefined,
        registerId: registerId ?? undefined,
        openingBalance: parseFloat(openingBalance) || 0,
      }),
    onSuccess: async (session) => {
      setDrawerSession(session.id)
      await queryClient.invalidateQueries({ queryKey: posKeys.drawer(locationId ?? '') })
      toast.success('Drawer opened')
      onOpenChange(false)
    },
    onError: (err) => toast.error(err.message),
  })

  const closeMutation = useMutation({
    mutationFn: () =>
      posMutations.closeDrawer(drawer!.id, {
        closingBalance: parseFloat(closingBalance) || 0,
        notes: notes || undefined,
      }),
    onSuccess: async (session) => {
      setDrawerSession(null)
      const overShort = parseFloat(session.overShort ?? '0')
      if (Math.abs(overShort) < 0.01) {
        toast.success('Drawer closed - balanced')
      } else {
        toast.warning(`Drawer closed - ${overShort > 0 ? 'over' : 'short'} $${Math.abs(overShort).toFixed(2)}`)
      }
      // Show Z report
      setClosedDrawerId(session.id)
      setShowZReport(true)
      await queryClient.invalidateQueries({ queryKey: posKeys.drawer(locationId ?? '') })
    },
    onError: (err) => toast.error(err.message),
  })

  const adjustMutation = useMutation({
    mutationFn: () =>
      posMutations.addAdjustment(drawer!.id, {
        type: adjustView!,
        amount: parseFloat(adjAmount) || 0,
        reason: adjReason,
      }),
    onSuccess: (adj) => {
      queryClient.invalidateQueries({ queryKey: posKeys.drawerAdjustments(drawer!.id) })
      toast.success(`${adj.type === 'cash_in' ? 'Cash added' : 'Cash removed'}: $${parseFloat(adj.amount).toFixed(2)}`)
      setAdjustView(null)
      setAdjAmount('')
      setAdjReason('')
    },
    onError: (err) => toast.error(err.message),
  })

  // Z Report view (shown after drawer close)
  if (showZReport && reportData) {
    const r = reportData
    return (
      <>
      <Dialog open={open} onOpenChange={(o) => { onOpenChange(o); if (!o) { setShowZReport(false); setClosedDrawerId(null) } }}>
        <DialogContent className="max-w-md max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>Z Report — Drawer Closed</DialogTitle>
          </DialogHeader>
          <DrawerReportView report={r} />
          <Button variant="outline" className="w-full" onClick={() => { setShowZReport(false); setClosedDrawerId(null); onOpenChange(false) }}>
            Done
          </Button>
        </DialogContent>
      </Dialog>
      </>
    )
  }

  // X Report view (mid-shift snapshot)
  if (showXReport && xReportData) {
    return (
      <>
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent className="max-w-md max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>X Report — Current Shift</DialogTitle>
          </DialogHeader>
          <DrawerReportView report={xReportData} />
          <Button variant="outline" className="w-full" onClick={() => setShowXReport(false)}>
            Back
          </Button>
        </DialogContent>
      </Dialog>
      </>
    )
  }

  // Adjustment entry view
  if (adjustView && isOpen) {
    const isCashIn = adjustView === 'cash_in'
    return (
      <>
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>{isCashIn ? 'Cash In' : 'Cash Out'}</DialogTitle>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Amount *</Label>
              <Input
                type="number"
                step="0.01"
                min="0.01"
                value={adjAmount}
                onChange={(e) => setAdjAmount(e.target.value)}
                placeholder="0.00"
                className="h-11 text-lg"
                autoFocus
              />
            </div>
            <div className="space-y-2">
              <Label>Reason *</Label>
              <Input
                value={adjReason}
                onChange={(e) => setAdjReason(e.target.value)}
                placeholder={isCashIn ? 'e.g. Extra change' : 'e.g. Bank deposit'}
                className="h-11"
              />
            </div>
            <div className="flex gap-2">
              <Button
                className="flex-1 h-12"
                onClick={() => adjustMutation.mutate()}
                disabled={!adjAmount || !adjReason || adjustMutation.isPending}
              >
                {adjustMutation.isPending ? 'Saving...' : isCashIn ? 'Add Cash' : 'Remove Cash'}
              </Button>
              <Button variant="outline" className="h-12" onClick={() => setAdjustView(null)}>
                Cancel
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>
      </>
    )
  }

  return (
    <>
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-sm">
        <DialogHeader>
          <DialogTitle>{isOpen ? 'Drawer' : 'Open Drawer'}</DialogTitle>
        </DialogHeader>

        {isOpen ? (
          <div className="space-y-4">
            <div className="text-sm space-y-1">
              <div className="flex justify-between">
                <span className="text-muted-foreground">Opening Balance</span>
                <span>${parseFloat(drawer!.openingBalance).toFixed(2)}</span>
              </div>
              <div className="flex justify-between">
                <span className="text-muted-foreground">Opened</span>
                <span>{new Date(drawer!.openedAt).toLocaleTimeString()}</span>
              </div>
            </div>

            {/* Cash In / Cash Out buttons */}
            <div className="grid grid-cols-2 gap-2">
              <Button
                variant="outline"
                className="h-11 gap-2"
                onClick={() => {
                  if (requiresOverride('cash_in_out')) {
                    setPendingAdjustView('cash_in')
                    setOverrideOpen(true)
                  } else {
                    setAdjustView('cash_in')
                  }
                }}
              >
                <ArrowDownToLine className="h-4 w-4 text-green-600" />
                Cash In
              </Button>
              <Button
                variant="outline"
                className="h-11 gap-2"
                onClick={() => {
                  if (requiresOverride('cash_in_out')) {
                    setPendingAdjustView('cash_out')
                    setOverrideOpen(true)
                  } else {
                    setAdjustView('cash_out')
                  }
                }}
              >
                <ArrowUpFromLine className="h-4 w-4 text-red-600" />
                Cash Out
              </Button>
            </div>

            {/* X Report button */}
            <Button variant="outline" className="w-full h-10 gap-2 text-sm" onClick={() => setShowXReport(true)}>
              Current Shift Report
            </Button>

            {/* Adjustment history */}
            {adjustments.length > 0 && (
              <>
                <Separator />
                <div className="space-y-1">
                  <span className="text-xs font-medium text-muted-foreground">Adjustments</span>
                  {adjustments.map((adj) => (
                    <div key={adj.id} className="flex items-center justify-between text-sm py-1">
                      <div className="flex items-center gap-2">
                        <Badge variant={adj.type === 'cash_in' ? 'default' : 'destructive'} className="text-[10px]">
                          {adj.type === 'cash_in' ? 'IN' : 'OUT'}
                        </Badge>
                        <span className="text-muted-foreground truncate max-w-[140px]">{adj.reason}</span>
                      </div>
                      <span className={adj.type === 'cash_in' ? 'text-green-600' : 'text-red-600'}>
                        {adj.type === 'cash_in' ? '+' : '-'}${parseFloat(adj.amount).toFixed(2)}
                      </span>
                    </div>
                  ))}
                </div>
              </>
            )}

            <Separator />

            {/* Close drawer */}
            <div className="space-y-2">
              <Label>Closing Balance *</Label>
              <Input
                type="number"
                step="0.01"
                min="0"
                value={closingBalance}
                onChange={(e) => setClosingBalance(e.target.value)}
                placeholder="Count the cash in the drawer"
                className="h-11 text-lg"
              />
            </div>
            <div className="space-y-2">
              <Label>Notes</Label>
              <Input
                value={notes}
                onChange={(e) => setNotes(e.target.value)}
                placeholder="End of shift notes"
                className="h-11"
              />
            </div>
            <Button
              className="w-full h-12"
              onClick={() => closeMutation.mutate()}
              disabled={!closingBalance || closeMutation.isPending}
            >
              {closeMutation.isPending ? 'Closing...' : 'Close Drawer'}
            </Button>
          </div>
        ) : (
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Opening Balance *</Label>
              <Input
                type="number"
                step="0.01"
                min="0"
                value={openingBalance}
                onChange={(e) => setOpeningBalance(e.target.value)}
                placeholder="Starting cash amount"
                className="h-11 text-lg"
                autoFocus
              />
            </div>
            <Button
              className="w-full h-12"
              onClick={() => openMutation.mutate()}
              disabled={!openingBalance || openMutation.isPending}
            >
              {openMutation.isPending ? 'Opening...' : 'Open Drawer'}
            </Button>
          </div>
        )}
      </DialogContent>
    </Dialog>

    <ManagerOverrideDialog
      open={overrideOpen}
      onOpenChange={setOverrideOpen}
      action={pendingAdjustView === 'cash_in' ? 'Cash In' : 'Cash Out'}
      onAuthorized={() => {
        if (pendingAdjustView) setAdjustView(pendingAdjustView)
        setPendingAdjustView(null)
      }}
    />
    </>
  )
}

// --- Shared report view used by both X and Z reports ---

const PAYMENT_LABELS: Record<string, string> = {
  cash: 'Cash',
  card_present: 'Card (Present)',
  card_keyed: 'Card (Keyed)',
  check: 'Check',
  account_charge: 'Account',
  unknown: 'Other',
}

function DrawerReportView({ report }: { report: any }) {
  const { session, sales, payments, discounts, cash, adjustments } = report

  return (
    <div className="space-y-4 text-sm">
      {/* Session info */}
      <div className="space-y-1">
        {session.register && <div className="flex justify-between"><span className="text-muted-foreground">Register</span><span>{session.register.name}</span></div>}
        {session.openedBy && <div className="flex justify-between"><span className="text-muted-foreground">Opened by</span><span>{session.openedBy.firstName} {session.openedBy.lastName}</span></div>}
        <div className="flex justify-between"><span className="text-muted-foreground">Opened</span><span>{new Date(session.openedAt).toLocaleString()}</span></div>
        {session.closedAt && (
          <>
            {session.closedBy && <div className="flex justify-between"><span className="text-muted-foreground">Closed by</span><span>{session.closedBy.firstName} {session.closedBy.lastName}</span></div>}
            <div className="flex justify-between"><span className="text-muted-foreground">Closed</span><span>{new Date(session.closedAt).toLocaleString()}</span></div>
          </>
        )}
      </div>

      <Separator />

      {/* Sales */}
      <div>
        <h4 className="font-semibold text-xs uppercase text-muted-foreground mb-2">Sales</h4>
        <div className="space-y-1">
          <div className="flex justify-between"><span>Transactions</span><span>{sales.transactionCount}</span></div>
          <div className="flex justify-between"><span>Gross Sales</span><span className="tabular-nums">${sales.grossSales.toFixed(2)}</span></div>
          {sales.refundTotal > 0 && <div className="flex justify-between text-red-600"><span>Refunds</span><span className="tabular-nums">-${sales.refundTotal.toFixed(2)}</span></div>}
          <div className="flex justify-between font-medium"><span>Net Sales</span><span className="tabular-nums">${sales.netSales.toFixed(2)}</span></div>
          {sales.voidCount > 0 && <div className="flex justify-between text-muted-foreground"><span>Voided</span><span>{sales.voidCount}</span></div>}
        </div>
      </div>

      <Separator />

      {/* Payment breakdown */}
      <div>
        <h4 className="font-semibold text-xs uppercase text-muted-foreground mb-2">Payments</h4>
        <div className="space-y-1">
          {Object.entries(payments as Record<string, { count: number; total: number }>).map(([method, data]) => (
            <div key={method} className="flex justify-between">
              <span>{PAYMENT_LABELS[method] ?? method} ({data.count})</span>
              <span className="tabular-nums">${data.total.toFixed(2)}</span>
            </div>
          ))}
          {Object.keys(payments).length === 0 && <p className="text-muted-foreground">No payments</p>}
        </div>
      </div>

      {/* Discounts */}
      {discounts.count > 0 && (
        <>
          <Separator />
          <div>
            <h4 className="font-semibold text-xs uppercase text-muted-foreground mb-2">Discounts</h4>
            <div className="flex justify-between"><span>Total ({discounts.count})</span><span className="tabular-nums text-green-600">-${discounts.total.toFixed(2)}</span></div>
          </div>
        </>
      )}

      <Separator />

      {/* Cash accountability */}
      <div>
        <h4 className="font-semibold text-xs uppercase text-muted-foreground mb-2">Cash</h4>
        <div className="space-y-1">
          <div className="flex justify-between"><span>Opening Balance</span><span className="tabular-nums">${cash.openingBalance.toFixed(2)}</span></div>
          <div className="flex justify-between"><span>Cash Sales</span><span className="tabular-nums">${cash.cashSales.toFixed(2)}</span></div>
          {cash.cashIn > 0 && <div className="flex justify-between text-green-600"><span>Cash In</span><span className="tabular-nums">+${cash.cashIn.toFixed(2)}</span></div>}
          {cash.cashOut > 0 && <div className="flex justify-between text-red-600"><span>Cash Out</span><span className="tabular-nums">-${cash.cashOut.toFixed(2)}</span></div>}
          <Separator />
          <div className="flex justify-between font-medium"><span>Expected</span><span className="tabular-nums">${cash.expectedBalance.toFixed(2)}</span></div>
          {cash.actualBalance !== null && (
            <>
              <div className="flex justify-between"><span>Actual Count</span><span className="tabular-nums">${cash.actualBalance.toFixed(2)}</span></div>
              <div className={`flex justify-between font-bold ${cash.overShort === 0 ? 'text-green-600' : 'text-red-600'}`}>
                <span>{cash.overShort! >= 0 ? 'Over' : 'Short'}</span>
                <span className="tabular-nums">${Math.abs(cash.overShort!).toFixed(2)}</span>
              </div>
            </>
          )}
        </div>
      </div>

      {/* Adjustments */}
      {adjustments.length > 0 && (
        <>
          <Separator />
          <div>
            <h4 className="font-semibold text-xs uppercase text-muted-foreground mb-2">Adjustments</h4>
            <div className="space-y-1">
              {adjustments.map((adj: any) => (
                <div key={adj.id} className="flex items-center justify-between text-xs">
                  <div className="flex items-center gap-2">
                    <Badge variant={adj.type === 'cash_in' ? 'default' : 'destructive'} className="text-[10px]">
                      {adj.type === 'cash_in' ? 'IN' : 'OUT'}
                    </Badge>
                    <span className="text-muted-foreground truncate max-w-[150px]">{adj.reason}</span>
                  </div>
                  <span className="tabular-nums">${parseFloat(adj.amount).toFixed(2)}</span>
                </div>
              ))}
            </div>
          </div>
        </>
      )}
    </div>
  )
}
