import { useState } from 'react';
import { LayoutGroup } from 'framer-motion';
import { ArrowDown, ArrowUp } from 'lucide-react';
import { cn, fmt } from '@/lib/utils';
import {
  Table, TableHeader, TableBody, TableHead, TableRow, TableCell,
} from '@/components/ui/table';
import { TRACKER_SORT_ASC, TRACKER_SORT_DEFAULT, moveInArray } from '@/lib/trackerUtils';
import { DEFAULT_TRACKER_TABLE_COLUMNS } from '@/lib/trackerTableColumns';
import { TrackerRow as Row } from '@/components/tracker/TrackerRow';
import { MobileTrackerRow } from '@/components/tracker/MobileTrackerRow';

function SortableHead({ sortKey, activeSortKey, sortDir, onSort, children, className }) {
  const active = activeSortKey === sortKey;
  const Icon = sortDir === TRACKER_SORT_ASC ? ArrowUp : ArrowDown;
  return (
    <TableHead
      aria-sort={active ? (sortDir === TRACKER_SORT_ASC ? 'ascending' : 'descending') : 'none'}
      className={cn('h-11 py-2.5', className)}
    >
      <button
        type="button"
        onClick={() => onSort?.(sortKey)}
        className={cn(
          'group inline-flex h-8 items-center gap-1.5 rounded-md px-2 text-[11px] font-semibold uppercase tracking-[0.08em] transition-all',
          'hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/60',
          active ? 'bg-accent/70 text-foreground shadow-sm' : 'text-muted-foreground'
        )}
      >
        <span>{children}</span>
        <Icon
          className={cn(
            'h-3.5 w-3.5 transition-opacity',
            active ? 'opacity-100' : 'opacity-0 group-hover:opacity-55'
          )}
          aria-hidden="true"
        />
      </button>
    </TableHead>
  );
}

export function TrackerBucket({
  label,
  rows,
  year,
  month,
  refresh,
  onEditBill,
  loading,
  onReorderRows,
  reorderEnabled,
  movingBillId,
  sortKey = TRACKER_SORT_DEFAULT,
  sortDir = TRACKER_SORT_ASC,
  onSort,
  driftedIds = new Set(),
  visibleColumns = DEFAULT_TRACKER_TABLE_COLUMNS,
}) {
  const [draggingId, setDraggingId] = useState(null);
  const [dropTargetId, setDropTargetId] = useState(null);
  const visibleColumnSet = new Set(visibleColumns);
  const showColumn = key => visibleColumnSet.has(key);
  const tableColSpan = 1 + visibleColumns.length;
  // Use actual_amount (if set) as the per-row threshold; exclude skipped rows from totals
  const activeRows    = rows.filter(r => !r.is_skipped);
  const totalThreshold = activeRows.reduce((s, r) => s + (r.actual_amount ?? r.expected_amount ?? 0), 0);
  const totalPaid      = activeRows.reduce((s, r) => s + (r.total_paid || 0), 0);
  const totalPaidTowardDue = activeRows.reduce((s, r) => {
    const threshold = Number(r.actual_amount ?? r.expected_amount ?? 0) || 0;
    const cappedPaid = Number(r.paid_toward_due);
    return s + (Number.isFinite(cappedPaid) ? cappedPaid : Math.min(Number(r.total_paid) || 0, threshold));
  }, 0);
  const totalOverpaid   = Math.max(totalPaid - totalPaidTowardDue, 0);
  const totalRemaining  = Math.max(totalThreshold - totalPaidTowardDue, 0);
  const skippedCount    = rows.length - activeRows.length;
  const pct             = totalThreshold > 0 ? Math.min((totalPaidTowardDue / totalThreshold) * 100, 100) : 0;
  const allPaid         = pct >= 100;

  function reorderByIndex(fromIndex, toIndex) {
    if (!reorderEnabled || fromIndex === toIndex || fromIndex < 0 || toIndex < 0) return;
    onReorderRows?.(moveInArray(rows, fromIndex, toIndex));
  }

  function dragPropsFor(row, index) {
    if (!reorderEnabled) return { draggable: false };
    return {
      draggable: true,
      isDragging: draggingId === row.id,
      isDropTarget: dropTargetId === row.id && draggingId !== row.id,
      onDragStart: (event) => {
        setDraggingId(row.id);
        event.dataTransfer.effectAllowed = 'move';
        event.dataTransfer.setData('text/plain', String(row.id));
      },
      onDragEnter: () => {
        if (draggingId && draggingId !== row.id) setDropTargetId(row.id);
      },
      onDragOver: (event) => {
        event.preventDefault();
        event.dataTransfer.dropEffect = 'move';
        if (draggingId && draggingId !== row.id) setDropTargetId(row.id);
      },
      onDrop: (event) => {
        event.preventDefault();
        const sourceId = Number(event.dataTransfer.getData('text/plain') || draggingId);
        const fromIndex = rows.findIndex(item => item.id === sourceId);
        reorderByIndex(fromIndex, index);
        setDraggingId(null);
        setDropTargetId(null);
      },
      onDragEnd: () => {
        setDraggingId(null);
        setDropTargetId(null);
      },
    };
  }

  function moveControlsFor(row, index) {
    return {
      enabled: !!reorderEnabled,
      moving: movingBillId === row.id,
      canMoveUp: index > 0,
      canMoveDown: index < rows.length - 1,
      onMoveUp: () => reorderByIndex(index, index - 1),
      onMoveDown: () => reorderByIndex(index, index + 1),
    };
  }

  return (
    <div className="rounded-xl border border-border/80 overflow-hidden bg-card/95 shadow-sm shadow-black/15">

      {/* Bucket header */}
      <div className="flex flex-col gap-2 bg-muted/35 px-3 py-3 border-b border-border/80 sm:px-5 md:flex-row md:items-center md:justify-between">
        <div className="flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1.5">
          <div className="flex min-w-0 items-center gap-2">
            <span className="truncate text-[11px] font-bold uppercase tracking-[0.12em] text-muted-foreground">
              {label}
            </span>
            {skippedCount > 0 && (
              <span className="shrink-0 text-[10px] text-muted-foreground/60">
                ({skippedCount} skipped)
              </span>
            )}
          </div>
          <div className="flex min-w-[7rem] items-center gap-2">
            <div className="h-1.5 w-16 rounded-full bg-border overflow-hidden sm:w-24">
              <div
                className={cn(
                  'h-full rounded-full transition-all duration-700',
                  allPaid ? 'bg-emerald-500' : 'bg-emerald-400/70',
                )}
                style={{ width: `${pct}%` }}
              />
            </div>
            <span className="text-[11px] font-mono text-muted-foreground/70">
              {Math.round(pct)}%
            </span>
          </div>
        </div>
        <div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-xs font-mono text-muted-foreground md:justify-end">
          <span className="whitespace-nowrap">
            <span className={cn(allPaid ? 'text-emerald-500' : 'text-foreground')}>
              {fmt(totalPaidTowardDue)}
            </span>
            <span className="text-muted-foreground/50 mx-1">/</span>
            {fmt(totalThreshold)}
            {totalOverpaid > 0 && (
              <span className="ml-1 text-emerald-500">+{fmt(totalOverpaid)}</span>
            )}
          </span>
          {!allPaid && totalRemaining > 0 && (
            <span className="text-[11px] text-muted-foreground/70">{fmt(totalRemaining)} left</span>
          )}
          {allPaid && (
            <span className="text-[11px] text-emerald-500">Done</span>
          )}
          {!reorderEnabled && rows.length > 1 && (
            <span className="hidden text-[11px] text-muted-foreground/60 xl:inline">Clear filters to reorder</span>
          )}
        </div>
      </div>

      <LayoutGroup id={`tracker-bucket-mobile-${label}`}>
      <div className="grid gap-3 p-3 lg:hidden" aria-busy={loading ? 'true' : 'false'}>
        {loading ? (
          Array.from({ length: 3 }).map((_, i) => (
            <div key={i} className="rounded-lg border border-border/60 bg-background/60 p-3 animate-pulse">
              <div className="flex min-w-0 items-start justify-between gap-3">
                <div className="min-w-0">
                  <div className="flex min-w-0 items-center gap-2">
                    <div className="h-1.5 w-1.5 shrink-0 rounded-full bg-muted" />
                    <div className="h-4 w-32 rounded-md bg-muted" />
                  </div>
                </div>
                <div className="h-5 w-20 rounded-md bg-muted" />
              </div>
              <div className="grid grid-cols-2 gap-x-3 gap-y-2 text-xs text-muted-foreground mt-2">
                <div>
                  <p className="uppercase tracking-wide text-muted-foreground/60">Expected</p>
                  <div className="h-3 w-20 rounded-md bg-muted mt-0.5" />
                </div>
                <div>
                  <p className="uppercase tracking-wide text-muted-foreground/60">Remaining</p>
                  <div className="h-3 w-20 rounded-md bg-muted mt-0.5" />
                </div>
              </div>
            </div>
          ))
        ) : rows.length === 0 ? (
          <div className="rounded-lg bg-muted/15 px-4 py-8 text-center text-sm text-muted-foreground">
            No bills match — try adjusting your filters.
          </div>
        ) : (
          rows.map((r, i) => (
            <MobileTrackerRow
              key={r.id}
              row={r}
              year={year}
              month={month}
              refresh={refresh}
              index={i}
              onEditBill={onEditBill}
              moveControls={moveControlsFor(r, i)}
              dragProps={dragPropsFor(r, i)}
              isDrifted={driftedIds.has(r.id)}
            />
          ))
        )}
      </div>
      </LayoutGroup>

      <div className="hidden lg:block" aria-busy={loading ? 'true' : 'false'}>
        <div className="overflow-x-auto">
          <Table className={cn(visibleColumns.length <= 4 ? 'min-w-[720px]' : 'min-w-[1120px]')}>
          <TableHeader>
            <TableRow className="border-border/80 bg-background/30 hover:bg-background/30">
              <SortableHead sortKey="name" activeSortKey={sortKey} sortDir={sortDir} onSort={onSort} className="w-[18%]">Bill</SortableHead>
              {showColumn('due') && (
                <SortableHead sortKey="due" activeSortKey={sortKey} sortDir={sortDir} onSort={onSort} className="w-[10%]">Due</SortableHead>
              )}
              {showColumn('expected') && (
                <SortableHead sortKey="expected" activeSortKey={sortKey} sortDir={sortDir} onSort={onSort} className="w-[10%] text-center">Expected</SortableHead>
              )}
              {showColumn('previous') && (
                <SortableHead sortKey="previous" activeSortKey={sortKey} sortDir={sortDir} onSort={onSort} className="w-[10%] text-center">Last Month</SortableHead>
              )}
              {showColumn('paid') && (
                <SortableHead sortKey="paid" activeSortKey={sortKey} sortDir={sortDir} onSort={onSort} className="w-[10%] text-center">Paid</SortableHead>
              )}
              {showColumn('paid_date') && (
                <SortableHead sortKey="paid_date" activeSortKey={sortKey} sortDir={sortDir} onSort={onSort} className="w-[10%]">Paid Date</SortableHead>
              )}
              {showColumn('status') && (
                <SortableHead sortKey="status" activeSortKey={sortKey} sortDir={sortDir} onSort={onSort} className="w-[9%] text-center">Status</SortableHead>
              )}
              {showColumn('action') && (
                <TableHead className="h-11 w-[10%] py-2.5 text-center text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">
                  Action
                </TableHead>
              )}
              {showColumn('notes') && (
                <TableHead className="h-11 w-[23%] py-2.5 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground border-l border-border/80 pl-4">
                  Notes
                </TableHead>
              )}
            </TableRow>
          </TableHeader>
          <TableBody>
            {loading ? (
              Array.from({ length: 5 }).map((_, i) => (
                <TableRow key={i} className="border-border/50">
                  <TableCell className="w-[18%] py-3">
                    <div className="flex items-center gap-2.5">
                      <div className="h-1.5 w-1.5 rounded-full bg-muted" />
                      <div className="h-4 w-48 rounded-md bg-muted" />
                    </div>
                  </TableCell>
                  {showColumn('due') && <TableCell className="w-[10%] py-3"><div className="h-3 w-20 rounded-md bg-muted" /></TableCell>}
                  {showColumn('expected') && <TableCell className="w-[10%] py-3 text-center"><div className="mx-auto h-3 w-20 rounded-md bg-muted" /></TableCell>}
                  {showColumn('previous') && <TableCell className="w-[10%] py-3 text-center"><div className="mx-auto h-3 w-20 rounded-md bg-muted" /></TableCell>}
                  {showColumn('paid') && <TableCell className="w-[10%] py-3"><div className="mx-auto h-7 w-24 rounded-md bg-muted" /></TableCell>}
                  {showColumn('paid_date') && <TableCell className="w-[10%] py-3"><div className="h-7 w-24 rounded-md bg-muted" /></TableCell>}
                  {showColumn('status') && <TableCell className="w-[9%] py-3"><div className="mx-auto h-5 w-20 rounded-md bg-muted" /></TableCell>}
                  {showColumn('action') && (
                    <TableCell className="w-[10%] py-3 text-center">
                      <div className="flex items-center justify-center gap-1">
                        <div className="h-7 w-20 rounded-md bg-muted" />
                        <div className="h-7 w-7 rounded-md bg-muted" />
                      </div>
                    </TableCell>
                  )}
                  {showColumn('notes') && (
                    <TableCell className="w-[23%] py-3 border-l border-border pl-4">
                      <div className="h-4 w-full rounded-md bg-muted" />
                    </TableCell>
                  )}
                </TableRow>
              ))
            ) : rows.length === 0 ? (
              <TableRow className="border-border/50">
                <TableCell colSpan={tableColSpan} className="py-10 text-center text-sm text-muted-foreground">
                  No bills match — try adjusting your filters.
                </TableCell>
              </TableRow>
            ) : (
              <LayoutGroup id={`tracker-bucket-table-${label}`}>
                {rows.map((r, i) => (
                  <Row
                    key={r.id}
                    row={r}
                    year={year}
                    month={month}
                    refresh={refresh}
                    index={i}
                    onEditBill={onEditBill}
                    moveControls={moveControlsFor(r, i)}
                    dragProps={dragPropsFor(r, i)}
                    isDrifted={driftedIds.has(r.id)}
                    visibleColumns={visibleColumns}
                  />
                ))}
              </LayoutGroup>
            )}
          </TableBody>
        </Table>
        </div>
      </div>
    </div>
  );
}
