'use client';

import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { X, Plus, Pin, PinOff, Trash2, ChevronUp, ChevronDown, Loader2 } from 'lucide-react';
import {
  fetchSavedViews, createSavedView, updateSavedView, deleteSavedView,
  type SavedView, type VideosQuery,
} from '@/lib/api';
import styles from './SavedViewManager.module.css';

interface Props {
  onClose: () => void;
  currentFilters: Partial<VideosQuery>;
  currentColumnsJson: Record<string, unknown>;
  currentSortJson: Record<string, unknown> | null;
}

export default function SavedViewManager({ onClose, currentFilters, currentColumnsJson, currentSortJson }: Props) {
  const qc = useQueryClient();
  const [newName, setNewName] = useState('');
  const [newDesc, setNewDesc] = useState('');
  const [pinNew, setPinNew] = useState(false);
  const [creating, setCreating] = useState(false);

  const { data: views = [], isLoading } = useQuery({
    queryKey: ['savedViews'],
    queryFn: fetchSavedViews,
    staleTime: 30_000,
  });

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ['savedViews'] });
    qc.invalidateQueries({ queryKey: ['savedViewTabs'] });
  };

  const createMut = useMutation({
    mutationFn: () => createSavedView({
      name: newName.trim(),
      description: newDesc.trim() || undefined,
      queryJson: currentFilters as Record<string, unknown>,
      columnsJson: currentColumnsJson,
      sortJson: currentSortJson,
      pinnedAsTab: pinNew,
      tabOrder: pinNew ? (views.filter((v) => v.pinnedAsTab).length) : undefined,
    }),
    onSuccess: () => { invalidate(); setNewName(''); setNewDesc(''); setPinNew(false); setCreating(false); },
  });

  const patchMut = useMutation({
    mutationFn: ({ id, data }: { id: string; data: Parameters<typeof updateSavedView>[1] }) =>
      updateSavedView(id, data),
    onSuccess: invalidate,
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteSavedView(id),
    onSuccess: invalidate,
  });

  const pinnedViews = views.filter((v) => v.pinnedAsTab).sort((a, b) => (a.tabOrder ?? 99) - (b.tabOrder ?? 99));
  const unpinnedViews = views.filter((v) => !v.pinnedAsTab).sort((a, b) => a.name.localeCompare(b.name));

  const moveTab = (view: SavedView, dir: -1 | 1) => {
    const idx = pinnedViews.findIndex((v) => v.id === view.id);
    const swapIdx = idx + dir;
    if (swapIdx < 0 || swapIdx >= pinnedViews.length) return;
    const swap = pinnedViews[swapIdx];
    Promise.all([
      patchMut.mutateAsync({ id: view.id, data: { tabOrder: swapIdx } }),
      patchMut.mutateAsync({ id: swap.id, data: { tabOrder: idx } }),
    ]);
  };

  return (
    <div className={styles.overlay} onClick={(e) => e.target === e.currentTarget && onClose()}>
      <div className={styles.modal}>
        <div className={styles.header}>
          <h2 className={styles.title}>Saved Views</h2>
          <button className={styles.closeBtn} onClick={onClose}><X size={18} /></button>
        </div>

        <div className={styles.body}>
          {/* Create new view */}
          {creating ? (
            <div className={styles.createForm}>
              <input
                className={styles.nameInput}
                placeholder="View name"
                value={newName}
                onChange={(e) => setNewName(e.target.value)}
                autoFocus
              />
              <input
                className={styles.descInput}
                placeholder="Description (optional)"
                value={newDesc}
                onChange={(e) => setNewDesc(e.target.value)}
              />
              <label className={styles.pinLabel}>
                <input type="checkbox" checked={pinNew} onChange={(e) => setPinNew(e.target.checked)} />
                Pin as tab
              </label>
              <div className={styles.createActions}>
                <button className="btn btn-secondary" onClick={() => setCreating(false)}>Cancel</button>
                <button
                  className="btn btn-primary"
                  disabled={!newName.trim() || createMut.isPending}
                  onClick={() => createMut.mutate()}
                >
                  {createMut.isPending ? <Loader2 size={14} className={styles.spin} /> : null}
                  Save view
                </button>
              </div>
            </div>
          ) : (
            <button className={styles.newViewBtn} onClick={() => setCreating(true)}>
              <Plus size={14} /> Save current filters as view…
            </button>
          )}

          {isLoading && <div className={styles.loading}><Loader2 size={18} className={styles.spin} /> Loading…</div>}

          {/* Pinned as tabs */}
          {pinnedViews.length > 0 && (
            <section>
              <div className={styles.sectionTitle}>Pinned Tabs</div>
              {pinnedViews.map((view, idx) => (
                <div key={view.id} className={styles.viewRow}>
                  <div className={styles.viewMeta}>
                    <span className={styles.viewName}>{view.name}</span>
                    {view.description && <span className={styles.viewDesc}>{view.description}</span>}
                  </div>
                  <div className={styles.viewActions}>
                    <button title="Move up" className={styles.iconBtn} disabled={idx === 0} onClick={() => moveTab(view, -1)}><ChevronUp size={14} /></button>
                    <button title="Move down" className={styles.iconBtn} disabled={idx === pinnedViews.length - 1} onClick={() => moveTab(view, 1)}><ChevronDown size={14} /></button>
                    <button title="Unpin" className={styles.iconBtn} onClick={() => patchMut.mutate({ id: view.id, data: { pinnedAsTab: false, tabOrder: null } })}><PinOff size={14} /></button>
                    <button title="Delete" className={`${styles.iconBtn} ${styles.iconBtnDanger}`} onClick={() => { if (confirm(`Delete "${view.name}"?`)) deleteMut.mutate(view.id); }}><Trash2 size={14} /></button>
                  </div>
                </div>
              ))}
            </section>
          )}

          {/* All other views */}
          {unpinnedViews.length > 0 && (
            <section>
              <div className={styles.sectionTitle}>All Views</div>
              {unpinnedViews.map((view) => (
                <div key={view.id} className={styles.viewRow}>
                  <div className={styles.viewMeta}>
                    <span className={styles.viewName}>{view.name}</span>
                    {view.description && <span className={styles.viewDesc}>{view.description}</span>}
                  </div>
                  <div className={styles.viewActions}>
                    <button title="Pin as tab" className={styles.iconBtn} onClick={() => patchMut.mutate({ id: view.id, data: { pinnedAsTab: true, tabOrder: pinnedViews.length } })}><Pin size={14} /></button>
                    <button title="Delete" className={`${styles.iconBtn} ${styles.iconBtnDanger}`} onClick={() => { if (confirm(`Delete "${view.name}"?`)) deleteMut.mutate(view.id); }}><Trash2 size={14} /></button>
                  </div>
                </div>
              ))}
            </section>
          )}

          {!isLoading && views.length === 0 && !creating && (
            <p className={styles.empty}>No saved views yet. Save your current filters to create one.</p>
          )}
        </div>
      </div>
    </div>
  );
}
