import { DownloadCsvButton } from '@/components/admin/download-csv-button';
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 { cn } from '@/lib/utils';
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 = {
  title?: string;
  dateFilter?: boolean | ReactNode;
  addButton?: ReactNode;
  className?: string;
  resource?: string;
  basePath?: string;
  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 TableBarDefault({
  title,
  addButton,
  dateFilter = true,
  className,
  resource,
  basePath = '/api/admin/export',
  searchFields = [],
  builder,
}: 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={cn(
        'relative z-10 flex h-[62px] items-center justify-between gap-2.5 rounded-t-xl bg-white p-2 dark:bg-secondary',
        className,
      )}
    >
      {title ? (
        <h2 className="px-4 text-xl font-medium text-black dark:text-white">
          {title}
        </h2>
      ) : (
        <>
          <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-muted">
                <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 && fields.length > 1 && (
              <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">
            {resource ? (
              <DownloadCsvButton resource={resource} basePath={basePath} />
            ) : (
              <></>
            )}

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