'use client';

import { useState, useRef, useEffect } from 'react';
import { Menu, Search, Sun, Moon, Eye, LogOut, Loader2, CloudUpload, CheckCircle2, XCircle, Clock, Loader } from 'lucide-react';
import { useRouter } from 'next/navigation';
import { useQuery, useMutation } from '@tanstack/react-query';
import { useUIStore } from '@/store/useUIStore';
import { useAuthStore } from '@/store/useAuthStore';
import { useTheme } from '@/hooks/useTheme';
import apiClient from '@/lib/api-client';
import { fetchSavedViews, fetchTemplates, bulkPreview, bulkApply, fetchSyncQueueStatus, type BulkActionType, type BulkPreviewResponse } from '@/lib/api';
import Modal from './Modal';
import f from './FormField.module.css';
import styles from './Header.module.css';

// ─── Bulk Action Modal ────────────────────────────────────────────────────────

const ACTION_LABELS: Record<BulkActionType, string> = {
  SET_PRIVACY: 'Set Privacy Status',
  SET_TEMPLATE: 'Assign Template',
  ADD_TAGS: 'Add Tags',
  REMOVE_TAGS: 'Remove Tags',
  SEARCH_REPLACE_TITLE: 'Search & Replace in Title',
};

function BulkModal({ onClose }: { onClose: () => void }) {
  const [step, setStep] = useState<'configure' | 'preview'>('configure');
  const [actionType, setActionType] = useState<BulkActionType>('SET_PRIVACY');
  const [targetType, setTargetType] = useState<'all' | 'view'>('all');
  const [savedViewId, setSavedViewId] = useState('');
  const [payload, setPayload] = useState<Record<string, string>>({});
  const [preview, setPreview] = useState<BulkPreviewResponse | null>(null);

  const { data: savedViews = [] } = useQuery({ queryKey: ['saved-views'], queryFn: fetchSavedViews });
  const { data: templates = [] } = useQuery({ queryKey: ['templates'], queryFn: fetchTemplates });

  const buildPayload = () => {
    if ((actionType === 'ADD_TAGS' || actionType === 'REMOVE_TAGS') && typeof payload.tags === 'string') {
      return { ...payload, tags: payload.tags.split(',').map((t) => t.trim()).filter(Boolean) };
    }
    return payload;
  };

  const previewMut = useMutation({
    mutationFn: () => bulkPreview({
      type: actionType,
      payload: buildPayload(),
      savedViewId: targetType === 'view' ? savedViewId : undefined,
    }),
    onSuccess: (data) => { setPreview(data); setStep('preview'); },
  });

  const applyMut = useMutation({
    mutationFn: () => bulkApply({
      type: actionType,
      payload: buildPayload(),
      savedViewId: targetType === 'view' ? savedViewId : undefined,
    }),
    onSuccess: onClose,
  });

  const setP = (key: string, val: string) => setPayload((p) => ({ ...p, [key]: val }));

  return (
    <Modal title="Bulk Change" onClose={onClose} width={640}>
      {step === 'configure' && (
        <>
          <div className={f.field}>
            <label className={f.label}>Action</label>
            <select className={f.select} value={actionType} onChange={(e) => { setActionType(e.target.value as BulkActionType); setPayload({}); }}>
              {(Object.keys(ACTION_LABELS) as BulkActionType[]).map((k) => (
                <option key={k} value={k}>{ACTION_LABELS[k]}</option>
              ))}
            </select>
          </div>

          {actionType === 'SET_PRIVACY' && (
            <div className={f.field}>
              <label className={f.label}>Privacy Status</label>
              <select className={f.select} value={payload.privacyStatus ?? 'PUBLIC'} onChange={(e) => setP('privacyStatus', e.target.value)}>
                <option value="PUBLIC">Public</option>
                <option value="PRIVATE">Private</option>
                <option value="UNLISTED">Unlisted</option>
              </select>
            </div>
          )}
          {actionType === 'SET_TEMPLATE' && (
            <div className={f.field}>
              <label className={f.label}>Template</label>
              <select className={f.select} value={payload.templateId ?? ''} onChange={(e) => setP('templateId', e.target.value)}>
                <option value="">— select —</option>
                {templates.map((t) => <option key={t.id} value={t.id}>{t.name}</option>)}
              </select>
            </div>
          )}
          {(actionType === 'ADD_TAGS' || actionType === 'REMOVE_TAGS') && (
            <div className={f.field}>
              <label className={f.label}>Tags (comma-separated)</label>
              <input className={f.input} value={payload.tags ?? ''} onChange={(e) => setP('tags', e.target.value)} placeholder="tag1, tag2, tag3" />
            </div>
          )}
          {actionType === 'SEARCH_REPLACE_TITLE' && (
            <div className={f.row}>
              <div className={f.field}>
                <label className={f.label}>Search</label>
                <input className={f.input} value={payload.search ?? ''} onChange={(e) => setP('search', e.target.value)} placeholder="text to find" />
              </div>
              <div className={f.field}>
                <label className={f.label}>Replace with</label>
                <input className={f.input} value={payload.replace ?? ''} onChange={(e) => setP('replace', e.target.value)} placeholder="replacement" />
              </div>
            </div>
          )}

          <div className={f.field}>
            <label className={f.label}>Target Videos</label>
            <select className={f.select} value={targetType} onChange={(e) => setTargetType(e.target.value as 'all' | 'view')}>
              <option value="all">All videos in team</option>
              <option value="view">Saved view</option>
            </select>
          </div>
          {targetType === 'view' && (
            <div className={f.field}>
              <label className={f.label}>Saved View</label>
              <select className={f.select} value={savedViewId} onChange={(e) => setSavedViewId(e.target.value)}>
                <option value="">— select —</option>
                {savedViews.map((v) => <option key={v.id} value={v.id}>{v.name}</option>)}
              </select>
            </div>
          )}

          {previewMut.isError && <p style={{ color: 'var(--color-error)', fontSize: 'var(--text-xs)' }}>Preview failed — check the backend logs.</p>}
          <div className={f.actions}>
            <button className="btn btn-secondary" onClick={onClose}>Cancel</button>
            <button className="btn btn-primary" onClick={() => previewMut.mutate()} disabled={previewMut.isPending}>
              {previewMut.isPending ? <Loader2 size={14} /> : <Eye size={14} />}
              Preview Changes
            </button>
          </div>
        </>
      )}

      {step === 'preview' && preview && (
        <>
          <p style={{ fontSize: 'var(--text-sm)', color: 'var(--color-text-muted)' }}>
            <strong>{preview.count}</strong> video{preview.count !== 1 ? 's' : ''} will be affected by <strong>{ACTION_LABELS[preview.type]}</strong>.
          </p>
          <div style={{ maxHeight: 320, overflowY: 'auto', border: '1px solid var(--color-border)', borderRadius: 'var(--radius-md)' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 'var(--text-xs)' }}>
              <thead>
                <tr style={{ borderBottom: '1px solid var(--color-border)', background: 'var(--color-surface-offset)' }}>
                  <th style={{ padding: '8px 12px', textAlign: 'left', color: 'var(--color-text-faint)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>Video</th>
                  <th style={{ padding: '8px 12px', textAlign: 'left', color: 'var(--color-text-faint)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>Before</th>
                  <th style={{ padding: '8px 12px', textAlign: 'left', color: 'var(--color-text-faint)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>After</th>
                </tr>
              </thead>
              <tbody>
                {preview.previews.slice(0, 50).map((p) => (
                  <tr key={p.videoId} style={{ borderBottom: '1px solid var(--color-divider)' }}>
                    <td style={{ padding: '8px 12px', color: 'var(--color-text-muted)', maxWidth: 200, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                      {p.before.title}
                    </td>
                    <td style={{ padding: '8px 12px', color: 'var(--color-text-faint)' }}>
                      {preview.type === 'SET_PRIVACY' && p.before.privacyStatus}
                      {preview.type === 'ADD_TAGS' && (p.before.tags ?? []).join(', ')}
                      {preview.type === 'REMOVE_TAGS' && (p.before.tags ?? []).join(', ')}
                      {preview.type === 'SEARCH_REPLACE_TITLE' && p.before.title}
                      {preview.type === 'SET_TEMPLATE' && (p.before.templateId ?? '—')}
                    </td>
                    <td style={{ padding: '8px 12px', color: 'var(--color-primary)', fontWeight: 600 }}>
                      {preview.type === 'SET_PRIVACY' && p.after.privacyStatus}
                      {preview.type === 'ADD_TAGS' && (p.after.tags ?? []).join(', ')}
                      {preview.type === 'REMOVE_TAGS' && (p.after.tags ?? []).join(', ')}
                      {preview.type === 'SEARCH_REPLACE_TITLE' && p.after.title}
                      {preview.type === 'SET_TEMPLATE' && (p.after.templateId ?? '—')}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
            {preview.previews.length > 50 && (
              <p style={{ padding: '8px 12px', color: 'var(--color-text-faint)', fontSize: 'var(--text-xs)' }}>
                + {preview.previews.length - 50} more videos not shown
              </p>
            )}
          </div>
          {applyMut.isError && <p style={{ color: 'var(--color-error)', fontSize: 'var(--text-xs)' }}>Apply failed — check the backend logs.</p>}
          <div className={f.actions}>
            <button className="btn btn-secondary" onClick={() => setStep('configure')}>Back</button>
            <button className="btn btn-primary" onClick={() => applyMut.mutate()} disabled={applyMut.isPending}>
              {applyMut.isPending ? <Loader2 size={14} /> : null}
              Apply to {preview.count} Video{preview.count !== 1 ? 's' : ''}
            </button>
          </div>
        </>
      )}
    </Modal>
  );
}

// ─── Sync Status Indicator ────────────────────────────────────────────────────

function SyncStatusIndicator() {
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

  const { data } = useQuery({
    queryKey: ['syncQueueStatus'],
    queryFn: fetchSyncQueueStatus,
    refetchInterval: (query) => {
      const d = query.state.data;
      if (d?.active.length) return 3_000;
      if (d?.waiting.length) return 8_000;
      return 30_000;
    },
  });

  useEffect(() => {
    if (!open) return;
    function handleClick(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);
    }
    document.addEventListener('mousedown', handleClick);
    return () => document.removeEventListener('mousedown', handleClick);
  }, [open]);

  const activeCount = data?.active.length ?? 0;
  const waitingCount = data?.waiting.length ?? 0;
  const pendingCount = activeCount + waitingCount;
  const hasFailures = (data?.recentFailed.length ?? 0) > 0;

  function formatRelative(iso: string | null) {
    if (!iso) return '';
    const diff = Date.now() - new Date(iso).getTime();
    const mins = Math.floor(diff / 60_000);
    if (mins < 1) return 'just now';
    if (mins < 60) return `${mins}m ago`;
    return `${Math.floor(mins / 60)}h ago`;
  }

  return (
    <div className={styles.syncWrap} ref={ref}>
      <button
        className={`${styles.syncBtn} ${pendingCount > 0 ? styles.syncBtnActive : ''} ${hasFailures && pendingCount === 0 ? styles.syncBtnFailed : ''}`}
        onClick={() => setOpen((o) => !o)}
        title="YouTube sync queue"
      >
        {activeCount > 0
          ? <Loader size={18} className={styles.syncSpinner} />
          : <CloudUpload size={18} />}
        {pendingCount > 0 && <span className={styles.syncBadge}>{pendingCount}</span>}
      </button>

      {open && (
        <div className={styles.syncDropdown}>
          <p className={styles.syncDropdownTitle}>YouTube sync queue</p>

          {activeCount === 0 && waitingCount === 0 && data?.recentFailed.length === 0 && data?.recentCompleted.length === 0 && (
            <p className={styles.syncEmpty}>Queue is empty.</p>
          )}

          {activeCount > 0 && (
            <div className={styles.syncSection}>
              <p className={styles.syncSectionLabel}>Processing</p>
              {data!.active.map((j) => (
                <div key={j.jobId} className={styles.syncRow}>
                  <Loader size={13} className={styles.syncSpinner} style={{ color: 'var(--color-primary)', flexShrink: 0 }} />
                  <span className={styles.syncRowTitle}>{j.videoTitle}</span>
                </div>
              ))}
            </div>
          )}

          {waitingCount > 0 && (
            <div className={styles.syncSection}>
              <p className={styles.syncSectionLabel}>Queued</p>
              {data!.waiting.map((j) => (
                <div key={j.jobId} className={styles.syncRow}>
                  <Clock size={13} style={{ color: 'var(--color-text-faint)', flexShrink: 0 }} />
                  <span className={styles.syncRowTitle}>{j.videoTitle}</span>
                </div>
              ))}
            </div>
          )}

          {(data?.recentFailed.length ?? 0) > 0 && (
            <div className={styles.syncSection}>
              <p className={styles.syncSectionLabel}>Failed</p>
              {data!.recentFailed.map((j) => (
                <div key={j.jobId} className={styles.syncRow}>
                  <XCircle size={13} style={{ color: 'var(--color-error)', flexShrink: 0 }} />
                  <div className={styles.syncRowInfo}>
                    <span className={styles.syncRowTitle}>{j.videoTitle}</span>
                    {j.failedReason && <span className={styles.syncRowSub}>{j.failedReason}</span>}
                  </div>
                  <span className={styles.syncRowTime}>{formatRelative(j.failedAt)}</span>
                </div>
              ))}
            </div>
          )}

          {(data?.recentCompleted.length ?? 0) > 0 && (
            <div className={styles.syncSection}>
              <p className={styles.syncSectionLabel}>Completed</p>
              {data!.recentCompleted.map((j) => (
                <div key={j.jobId} className={styles.syncRow}>
                  <CheckCircle2 size={13} style={{ color: 'var(--color-success, #22c55e)', flexShrink: 0 }} />
                  <span className={styles.syncRowTitle}>{j.videoTitle}</span>
                  <span className={styles.syncRowTime}>{formatRelative(j.completedAt)}</span>
                </div>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ─── Header ───────────────────────────────────────────────────────────────────

export default function Header() {
  const { toggleSidebar } = useUIStore();
  const { theme, toggleTheme } = useTheme();
  const { user, clearAuth } = useAuthStore();
  const router = useRouter();
  const [bulkOpen, setBulkOpen] = useState(false);
  const searchRef = useRef<HTMLInputElement>(null);

  async function handleLogout() {
    try { await apiClient.post('/auth/logout'); } catch {}
    clearAuth();
    document.cookie = 'sf_session=; path=/; max-age=0';
    router.replace('/login');
  }

  function handleSearch(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === 'Enter') {
      const q = (e.target as HTMLInputElement).value.trim();
      if (q) router.push(`/videos?search=${encodeURIComponent(q)}`);
    }
  }

  return (
    <>
      <header className={styles.header}>
        <div className={styles.left}>
          <button onClick={toggleSidebar} className={styles.menuBtn}>
            <Menu size={20} />
          </button>
          <label className={styles.search}>
            <Search size={18} />
            <input ref={searchRef} type="text" placeholder="Search videos… (Enter)" onKeyDown={handleSearch} />
          </label>
        </div>

        <div className={styles.right}>
          <SyncStatusIndicator />
          <button className={styles.btnSecondary} onClick={toggleTheme}>
            {theme === 'light' ? <Moon size={18} /> : <Sun size={18} />}
            <span>Theme</span>
          </button>
          <button className={styles.btnSecondary} onClick={() => setBulkOpen(true)}>
            <Eye size={18} />
            <span>Bulk change</span>
          </button>
          {user && (
            <div className={styles.userArea}>
              <span className={styles.teamBadge}>{user.teamRole}</span>
              <span className={styles.userName}>{user.name}</span>
              <button onClick={handleLogout} className={styles.logoutBtn} title="Sign out">
                <LogOut size={16} />
              </button>
            </div>
          )}
        </div>
      </header>

      {bulkOpen && <BulkModal onClose={() => setBulkOpen(false)} />}
    </>
  );
}
