"use client";

import { useMemo, useState } from "react";
import { BookmarkPlus, Star, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import type { SavedView } from "@/types";

interface SavedViewPreset<TFilters extends object> {
  id: string;
  label: string;
  filters: Partial<TFilters>;
}

interface SavedViewsBarProps<TFilters extends object> {
  filters: TFilters;
  emptyFilters: TFilters;
  views: SavedView[];
  builtInViews?: SavedViewPreset<TFilters>[];
  title?: string;
  description?: string;
  onApply: (filters: TFilters) => void;
  onCreate: (name: string, filters: TFilters) => Promise<void>;
  onDelete: (id: string) => Promise<void>;
  onToggleFavorite?: (id: string, isFavorite: boolean) => Promise<void>;
}

function normalizeFilters<TFilters extends object>(
  value: Record<string, unknown>,
  emptyFilters: TFilters
): TFilters {
  return {
    ...emptyFilters,
    ...Object.fromEntries(
      Object.entries(value).filter(([, entry]) => typeof entry === "string")
    ),
  } as TFilters;
}

export function SavedViewsBar<TFilters extends object>({
  filters,
  emptyFilters,
  views,
  builtInViews = [],
  title = "Saved views",
  description = "Reuse your most important filter combinations without rebuilding them.",
  onApply,
  onCreate,
  onDelete,
  onToggleFavorite,
}: SavedViewsBarProps<TFilters>) {
  const [creating, setCreating] = useState(false);
  const [newViewName, setNewViewName] = useState("");
  const [saving, setSaving] = useState(false);

  const serializedFilters = useMemo(() => JSON.stringify(filters), [filters]);

  return (
    <div className="space-y-3 rounded-2xl border border-border/60 bg-card p-4">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div>
          <p className="text-sm font-semibold">{title}</p>
          <p className="text-sm text-muted-foreground">{description}</p>
        </div>
        <Button
          type="button"
          size="sm"
          variant="outline"
          onClick={() => setCreating((value) => !value)}
        >
          <BookmarkPlus className="h-4 w-4" />
          Save current view
        </Button>
      </div>

      <div className="flex flex-wrap gap-2">
        {builtInViews.map((view) => {
          const builtInFilters = { ...emptyFilters, ...view.filters };
          const isActive = JSON.stringify(builtInFilters) === serializedFilters;

          return (
            <button
              key={view.id}
              type="button"
              onClick={() => onApply(builtInFilters)}
              className={`rounded-full border px-3 py-1.5 text-sm transition-colors ${
                isActive
                  ? "border-primary bg-primary text-primary-foreground"
                  : "border-border bg-background text-muted-foreground hover:bg-accent"
              }`}
            >
              {view.label}
            </button>
          );
        })}

        {views.map((view) => {
          const viewFilters = normalizeFilters(
            view.filters as Record<string, unknown>,
            emptyFilters
          );
          const isActive = JSON.stringify(viewFilters) === serializedFilters;

          return (
            <div
              key={view.id}
              className={`inline-flex items-center gap-1 rounded-full border pr-1 ${
                isActive
                  ? "border-primary bg-primary text-primary-foreground"
                  : "border-border bg-background text-foreground"
              }`}
            >
              <button
                type="button"
                onClick={() => onApply(viewFilters)}
                className="px-3 py-1.5 text-sm"
              >
                {view.name}
              </button>
              {onToggleFavorite && (
                <button
                  type="button"
                  onClick={() => {
                    void onToggleFavorite(view.id, !view.is_favorite);
                  }}
                  className={`rounded-full p-1 ${
                    isActive
                      ? "text-primary-foreground/80 hover:bg-primary-foreground/10"
                      : "text-muted-foreground hover:bg-accent"
                  }`}
                  title={view.is_favorite ? "Remove favorite" : "Mark as favorite"}
                >
                  <Star
                    className={`h-3.5 w-3.5 ${view.is_favorite ? "fill-current" : ""}`}
                  />
                </button>
              )}
              <button
                type="button"
                onClick={() => {
                  void onDelete(view.id);
                }}
                className={`rounded-full p-1 ${
                  isActive
                    ? "text-primary-foreground/80 hover:bg-primary-foreground/10"
                    : "text-muted-foreground hover:bg-accent"
                }`}
                title="Delete view"
              >
                <X className="h-3.5 w-3.5" />
              </button>
            </div>
          );
        })}
      </div>

      {creating && (
        <div className="flex flex-col gap-2 rounded-xl border border-border/60 bg-background/70 p-3 sm:flex-row">
          <Input
            value={newViewName}
            onChange={(event) => setNewViewName(event.target.value)}
            placeholder="Name this view..."
            className="h-9"
          />
          <div className="flex gap-2">
            <Button
              type="button"
              size="sm"
              disabled={!newViewName.trim() || saving}
              onClick={() => {
                void (async () => {
                  setSaving(true);
                  try {
                    await onCreate(newViewName.trim(), filters);
                    setNewViewName("");
                    setCreating(false);
                  } finally {
                    setSaving(false);
                  }
                })();
              }}
            >
              {saving ? "Saving..." : "Save"}
            </Button>
            <Button
              type="button"
              size="sm"
              variant="ghost"
              onClick={() => {
                setCreating(false);
                setNewViewName("");
              }}
            >
              Cancel
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
