import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from '@/components/ui/input-group';
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover';
import { useQueryBuilder } from '@cgarciagarcia/react-query-builder';
import {
  CalendarDotsIcon,
  CaretDownIcon,
  MagnifyingGlassIcon,
} from '@phosphor-icons/react';
import dayjs from 'dayjs';
import { ReactNode, useState } from 'react';
import type { DateRange } from 'react-day-picker';
import { useTranslation } from 'react-i18next';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '../ui/dropdown-menu';

type SearchField = string | { field: string; label: string };

type ToolbarProps = {
  dateFilter?: boolean | ReactNode;
  addButton?: ReactNode;
  downloadCsvButton?: ReactNode;
  searchFields?: SearchField[];
  builder?: ReturnType<typeof useQueryBuilder>;
};

function toFieldEntry(f: SearchField): { field: string; label: string } {
  if (typeof f === 'string') {
    const label = f
      .replace(/\./g, ' ')
      .replace(/_/g, ' ')
      .replace(/\b\w/g, (c) => c.toUpperCase());
    return { field: f, label };
  }
  return f;
}

export function TableBar({
  addButton,
  dateFilter = true,
  downloadCsvButton = true,
  searchFields = [],
  builder = undefined,
}: ToolbarProps) {
  const { t } = useTranslation();
  const fields = searchFields.map(toFieldEntry);
  const [search, setSearch] = useState({
    field: fields[0]?.field ?? '',
    value: '',
  });
  const [dateOpen, setDateOpen] = useState(false);
  const [range, setRange] = useState<DateRange | undefined>();

  const activeLabel =
    fields.find((f) => f.field === search.field)?.label ?? t('Select');

  const dateLabel = range?.from
    ? range.to
      ? `${dayjs(range.from).format('MMM D')} – ${dayjs(range.to).format('MMM D, YYYY')}`
      : dayjs(range.from).format('MMM D, YYYY')
    : t('All Time');

  const handleRangeSelect = (newRange: DateRange | undefined) => {
    setRange(newRange);
    builder?.removeParam('from', 'to');
    if (newRange?.from)
      builder?.setParam('from', dayjs(newRange.from).format('YYYY-MM-DD'));
    if (newRange?.to)
      builder?.setParam('to', dayjs(newRange.to).format('YYYY-MM-DD'));
  };

  const handleClear = () => {
    setRange(undefined);
    builder?.removeParam('from', 'to');
  };

  return (
    <div className="relative z-10 flex justify-between gap-2.5 rounded-t-xl bg-white p-2">
      <div className="flex items-center gap-2.5">
        {dateFilter === true && (
          <Popover open={dateOpen} onOpenChange={setDateOpen}>
            <PopoverTrigger asChild>
              <Button variant="ghostPrimary" className="hidden md:flex">
                <CalendarDotsIcon weight="bold" />
                {dateLabel}
                <CaretDownIcon weight="bold" />
              </Button>
            </PopoverTrigger>
            <PopoverContent className="w-auto p-0" align="start">
              <div className="border-b p-3">
                <p className="text-sm font-medium">{t('Date Range')}</p>
                <p className="text-xs text-muted-foreground">
                  {dateLabel} - {t('leave empty to show all records')}
                </p>
              </div>

              <Calendar
                mode="range"
                selected={range}
                onSelect={handleRangeSelect}
                numberOfMonths={2}
                disabled={{ after: new Date() }}
              />

              <div className="flex items-center justify-between gap-2 border-t p-3">
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={handleClear}
                  disabled={!range}
                >
                  {t('Clear')}
                </Button>
                <Button size="sm" onClick={() => setDateOpen(false)}>
                  {t('Apply')}
                </Button>
              </div>
            </PopoverContent>
          </Popover>
        )}

        {dateFilter !== true && dateFilter}

        {searchFields.length > 0 && (
          <InputGroup className="max-w-80 border-0 bg-black/5">
            <InputGroupInput
              placeholder={t('Search...')}
              value={search.value}
              onChange={(e) => {
                builder?.removeFilter(search.field);
                if (e.target.value)
                  builder?.filter(search.field, e.target.value);
                setSearch((prev) => ({ ...prev, value: e.target.value }));
              }}
            />
            <InputGroupAddon>
              <MagnifyingGlassIcon />
            </InputGroupAddon>
          </InputGroup>
        )}
        {builder && (
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button
                variant="outline"
                className="hidden h-full w-36 justify-between md:flex"
              >
                <span className="truncate">{activeLabel}</span>
                <CaretDownIcon weight="bold" className="shrink-0" />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent>
              {fields.map((f) => (
                <DropdownMenuItem
                  key={f.field}
                  onClick={() => {
                    if (search.field === f.field) return;
                    builder?.removeFilter(search.field);
                    if (search.value) builder?.filter(f.field, search.value);
                    setSearch((prev) => ({ ...prev, field: f.field }));
                  }}
                >
                  {f.label}
                </DropdownMenuItem>
              ))}
            </DropdownMenuContent>
          </DropdownMenu>
        )}
      </div>

      <div className="flex items-center gap-2.5">
        {downloadCsvButton}

        {addButton}
      </div>
    </div>
  );
}
