import { debounceStrategy, usePacedMutations } from '@tanstack/react-db';
import { ArrowDownAz, ArrowDownZa, Filter, Type } from 'lucide-react';
import { Resizable } from 're-resizable';
import { Fragment, useRef, useState } from 'react';
import { useDrop } from 'react-dnd';

import { LocalNode } from '@colanode/client/types';
import { SpecialId } from '@colanode/core';
import { Input } from '@colanode/ui/components/ui/input';
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@colanode/ui/components/ui/popover';
import { Separator } from '@colanode/ui/components/ui/separator';
import { useDatabase } from '@colanode/ui/contexts/database';
import { useDatabaseView } from '@colanode/ui/contexts/database-view';
import { useWorkspace } from '@colanode/ui/contexts/workspace';
import { applyNodeTransaction } from '@colanode/ui/lib/nodes';
import { cn } from '@colanode/ui/lib/utils';

export const TableViewNameHeader = () => {
  const workspace = useWorkspace();
  const database = useDatabase();
  const view = useDatabaseView();

  const [openPopover, setOpenPopover] = useState(false);

  const resize = usePacedMutations<number, LocalNode>({
    onMutate: (value) => {
      workspace.collections.nodes.update(view.id, (draft) => {
        if (draft.type !== 'database_view') {
          return;
        }

        if (draft.nameWidth === value) {
          return;
        }

        draft.nameWidth = value;
      });
    },
    mutationFn: async ({ transaction }) => {
      await applyNodeTransaction(workspace.userId, transaction);
    },
    strategy: debounceStrategy({ wait: 500 }),
  });

  const [dropMonitor, dropRef] = useDrop({
    accept: 'table-field-header',
    drop: () => ({
      after: 'name',
    }),
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  });

  const divRef = useRef<HTMLDivElement>(null);
  const dropDivRef = dropRef(divRef);

  return (
    <Resizable
      defaultSize={{
        width: `${view.nameWidth}px`,
        height: '2rem',
      }}
      minWidth={300}
      maxWidth={500}
      size={{ width: `${view.nameWidth}px`, height: '2rem' }}
      enable={{
        bottom: false,
        bottomLeft: false,
        bottomRight: false,
        left: false,
        right: database.canEdit && !database.isLocked,
        top: false,
        topLeft: false,
        topRight: false,
      }}
      handleClasses={{
        right: 'opacity-0 hover:opacity-100 bg-blue-300 dark:bg-blue-900',
      }}
      handleStyles={{
        right: {
          width: '3px',
          right: '-3px',
        },
      }}
      onResize={(_, __, ref) => {
        const newWidth = ref.offsetWidth;
        resize(newWidth);
      }}
    >
      <Popover modal={true} open={openPopover} onOpenChange={setOpenPopover}>
        <PopoverTrigger asChild>
          <div
            className={cn(
              'flex h-8 w-full cursor-pointer flex-row items-center gap-1 p-1 text-sm hover:bg-accent',
              dropMonitor.isOver && dropMonitor.canDrop
                ? 'border-r-2 border-blue-300 dark:border-blue-900'
                : 'border-r'
            )}
            ref={dropDivRef as React.Ref<HTMLDivElement>}
          >
            <Type className="size-4" />
            <p>{database.nameField?.name ?? 'Name'}</p>
          </div>
        </PopoverTrigger>
        <PopoverContent className="ml-1 flex w-72 flex-col gap-1 p-2 text-sm">
          <div className="p-1">
            <Input
              value={database.nameField?.name ?? 'Name'}
              readOnly={!database.canEdit || database.isLocked}
              onChange={(e) => {
                const newName = e.target.value;
                if (newName === database.nameField?.name) return;
                const nodes = workspace.collections.nodes;
                nodes.update(database.id, (draft) => {
                  if (draft.type !== 'database') {
                    return;
                  }

                  draft.nameField = { name: newName };
                });
              }}
            />
          </div>
          <Separator />
          {database.canEdit && !database.isLocked && (
            <Fragment>
              <div
                className="flex cursor-pointer flex-row items-center gap-2 p-1 hover:bg-accent rounded-sm"
                onClick={() => {
                  view.initFieldSort(SpecialId.Name, 'asc');
                  setOpenPopover(false);
                }}
              >
                <ArrowDownAz className="size-4" />
                <span>Sort ascending</span>
              </div>

              <div
                className="flex cursor-pointer flex-row items-center gap-2 p-1 hover:bg-accent rounded-sm"
                onClick={() => {
                  view.initFieldSort(SpecialId.Name, 'desc');
                  setOpenPopover(false);
                }}
              >
                <ArrowDownZa className="size-4" />
                <span>Sort descending</span>
              </div>
            </Fragment>
          )}
          <div
            className="flex cursor-pointer flex-row items-center gap-2 p-1 hover:bg-accent rounded-sm"
            onClick={() => {
              view.initFieldFilter(SpecialId.Name);
              setOpenPopover(false);
            }}
          >
            <Filter className="size-4" />
            <span>Filter</span>
          </div>
        </PopoverContent>
      </Popover>
    </Resizable>
  );
};
