import { useState, useEffect } from 'react';
import { Navigate } from 'react-router-dom';
import { apiFetch } from '../lib/api';
import { useAuthContext } from '../context/AuthContext';

const API_BASE = import.meta.env.VITE_API_URL || '/api';

// ── Types ────────────────────────────────────────────────────────────────────

interface Video {
  id: string;
  title: string;
  storageType: string;
  storageKey: string;
  requiredLevel: number;
  isPublished: boolean;
  createdAt: string;
}

interface Plan {
  id: string;
  slug: string;
  name: string;
  level: number;
  priceInCents: number;
  isActive: boolean;
}

interface AdminUser {
  id: string;
  email: string | null;
  nickname: string;
  isActive: boolean;
  createdAt: string;
  roles: { id: string; slug: string; name: string }[];
  activeSubscription: {
    id: string;
    status: string;
    endsAt: string | null;
    plan: Plan;
  } | null;
}

// ── Tabs ─────────────────────────────────────────────────────────────────────

type Tab = 'videos' | 'users' | 'plans';

export default function AdminPage() {
  const { user, loading: authLoading } = useAuthContext();
  const [tab, setTab] = useState<Tab>('videos');

  if (authLoading) return null;
  if (!user?.roles?.some((r) => r === 'admin' || r === 'super_admin')) return <Navigate to="/" replace />;

  return (
    <div className="flex flex-col gap-6">
      <div className="flex items-center gap-1 border-b border-od-border pb-4">
        {(['videos', 'users', 'plans'] as Tab[]).map((t) => (
          <button
            key={t}
            onClick={() => setTab(t)}
            className={`rounded px-3 py-1.5 font-mono text-xs transition-colors ${
              tab === t
                ? 'bg-od-surface text-od-accent border border-od-accent'
                : 'text-od-muted hover:text-od-text'
            }`}
          >
            {t}
          </button>
        ))}
      </div>

      {tab === 'videos' && <VideosTab />}
      {tab === 'users'  && <UsersTab />}
      {tab === 'plans'  && <PlansTab />}
    </div>
  );
}

// ── Videos tab ───────────────────────────────────────────────────────────────

function VideosTab() {
  const [videos, setVideos] = useState<Video[]>([]);
  const [loading, setLoading] = useState(true);
  const [fetchError, setFetchError] = useState<string | null>(null);
  const [actionError, setActionError] = useState<string | null>(null);
  const [form, setForm] = useState({
    title: '', storageType: 'youtube', storageKey: '',
    requiredLevel: 0, isPublished: false,
  });
  const [saving, setSaving] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    apiFetch<{ success: boolean; data: { videos: Video[] } }>('/admin/videos')
      .then((r) => setVideos(r.data.videos))
      .catch(() => setFetchError('Impossible de charger les vidéos.'))
      .finally(() => setLoading(false));
  }, []);

  async function handleFileUpload(file: File) {
    setUploading(true);
    setUploadError(null);
    setForm((f) => ({ ...f, storageKey: '' }));
    try {
      const fd = new FormData();
      fd.append('file', file);
      const res = await fetch(`${API_BASE}/admin/videos/upload`, {
        method: 'POST',
        credentials: 'include',
        body: fd,
      });
      if (!res.ok) throw new Error(`${res.status}`);
      const r = await res.json() as { success: boolean; data: { storageKey: string; storageType: string } };
      setForm((f) => ({ ...f, storageKey: r.data.storageKey, storageType: r.data.storageType }));
    } catch {
      setUploadError('Échec de l\'upload — vérifier format (mp4/webm, 4 Go max).');
    }
    setUploading(false);
  }

  async function handleCreate(e: React.FormEvent) {
    e.preventDefault();
    if (!form.title || !form.storageKey || saving) return;
    setSaving(true);
    setError(null);
    try {
      const r = await apiFetch<{ success: boolean; data: { video: Video } }>(
        '/admin/videos',
        { method: 'POST', body: JSON.stringify(form) }
      );
      setVideos((v) => [r.data.video, ...v]);
      setForm({ title: '', storageType: 'youtube', storageKey: '', requiredLevel: 0, isPublished: false });
    } catch {
      setError('Erreur lors de la création.');
    }
    setSaving(false);
  }

  async function togglePublish(video: Video) {
    setActionError(null);
    try {
      const r = await apiFetch<{ success: boolean; data: { video: Video } }>(
        `/admin/videos/${video.id}`,
        { method: 'PATCH', body: JSON.stringify({ isPublished: !video.isPublished }) }
      );
      setVideos((v) => v.map((x) => x.id === video.id ? r.data.video : x));
    } catch {
      setActionError('Impossible de modifier la vidéo.');
    }
  }

  async function handleDelete(id: string) {
    if (!confirm('Supprimer cette vidéo ?')) return;
    setActionError(null);
    try {
      await apiFetch(`/admin/videos/${id}`, { method: 'DELETE' });
      setVideos((v) => v.filter((x) => x.id !== id));
    } catch {
      setActionError('Impossible de supprimer la vidéo.');
    }
  }

  return (
    <div className="flex flex-col gap-6">

      {/* Formulaire création */}
      <form onSubmit={handleCreate} className="flex flex-col gap-3 rounded border border-od-border bg-od-surface p-4">
        <p className="font-mono text-xs text-od-muted uppercase tracking-widest">Nouvelle vidéo</p>

        <input
          value={form.title}
          onChange={(e) => setForm((f) => ({ ...f, title: e.target.value }))}
          placeholder="Titre"
          required
          className="rounded border border-od-border bg-od-bg px-3 py-2 text-sm text-od-text placeholder-od-muted outline-none focus:border-od-accent"
        />

        <div className="flex gap-2">
          <select
            value={form.storageType}
            onChange={(e) => setForm((f) => ({ ...f, storageType: e.target.value, storageKey: '' }))}
            className="rounded border border-od-border bg-od-bg px-3 py-2 text-sm text-od-text outline-none focus:border-od-accent"
          >
            <option value="youtube">YouTube</option>
            <option value="local">Local</option>
            <option value="s3">S3</option>
            <option value="external">External</option>
          </select>
          {form.storageType === 'local' ? (
            <div className="flex flex-1 flex-col gap-1">
              <input
                type="file"
                accept="video/mp4,video/webm"
                disabled={uploading}
                onChange={(e) => { const f = e.target.files?.[0]; if (f) handleFileUpload(f); }}
                className="flex-1 rounded border border-od-border bg-od-bg px-3 py-2 text-sm text-od-text outline-none focus:border-od-accent file:mr-2 file:rounded file:border-0 file:bg-od-surface file:px-2 file:py-0.5 file:font-mono file:text-xs file:text-od-muted"
              />
              {uploading && <p className="font-mono text-xs text-od-muted">Envoi en cours…</p>}
              {uploadError && <p className="font-mono text-xs text-od-crit">{uploadError}</p>}
              {!uploading && !uploadError && form.storageKey && (
                <p className="font-mono text-xs text-od-ok">✓ Upload réussi</p>
              )}
            </div>
          ) : (
            <input
              value={form.storageKey}
              onChange={(e) => setForm((f) => ({ ...f, storageKey: e.target.value }))}
              placeholder={form.storageType === 'youtube' ? 'ID YouTube (ex: dQw4w9WgXcQ)' : 'Chemin / URL'}
              required
              className="flex-1 rounded border border-od-border bg-od-bg px-3 py-2 text-sm text-od-text placeholder-od-muted outline-none focus:border-od-accent"
            />
          )}
        </div>

        <div className="flex items-center gap-4">
          <label className="flex items-center gap-2 text-sm text-od-muted">
            Niveau requis
            <input
              type="number"
              min={0}
              value={form.requiredLevel}
              onChange={(e) => setForm((f) => ({ ...f, requiredLevel: parseInt(e.target.value) || 0 }))}
              className="w-16 rounded border border-od-border bg-od-bg px-2 py-1 text-sm text-od-text outline-none focus:border-od-accent"
            />
          </label>
          <label className="flex items-center gap-2 text-sm text-od-muted">
            <input
              type="checkbox"
              checked={form.isPublished}
              onChange={(e) => setForm((f) => ({ ...f, isPublished: e.target.checked }))}
            />
            Publié
          </label>
        </div>

        {error && <p className="text-xs text-od-crit">{error}</p>}
        <button
          type="submit"
          disabled={saving || uploading}
          className="self-start rounded border border-od-accent px-4 py-1.5 font-mono text-xs text-od-accent hover:bg-od-accent hover:text-od-bg transition-colors disabled:opacity-40"
        >
          {saving ? '…' : 'Créer'}
        </button>
      </form>

      {/* Liste */}
      {loading ? (
        <div className="flex flex-col gap-2">
          {[...Array(3)].map((_, i) => <div key={i} className="h-12 rounded border border-od-border animate-pulse" />)}
        </div>
      ) : fetchError ? (
        <p className="text-sm text-od-crit">{fetchError}</p>
      ) : (
        <div className="flex flex-col gap-2">
          {actionError && <p className="text-xs text-od-crit">{actionError}</p>}
          {videos.map((v) => (
            <div key={v.id} className="flex items-center gap-3 rounded border border-od-border bg-od-surface px-4 py-3">
              <div className="flex-1 min-w-0">
                <p className="text-sm text-od-text truncate">{v.title}</p>
                <p className="font-mono text-xs text-od-muted">{v.storageType} · niveau {v.requiredLevel}</p>
              </div>
              <button
                onClick={() => togglePublish(v)}
                className={`font-mono text-xs px-2 py-0.5 rounded border transition-colors ${
                  v.isPublished
                    ? 'border-od-accent text-od-accent hover:bg-od-accent hover:text-od-bg'
                    : 'border-od-border text-od-muted hover:border-od-accent hover:text-od-accent'
                }`}
              >
                {v.isPublished ? 'publié' : 'brouillon'}
              </button>
              <button
                onClick={() => handleDelete(v.id)}
                className="font-mono text-xs text-od-muted hover:text-od-crit transition-colors"
              >
                ✕
              </button>
            </div>
          ))}
          {videos.length === 0 && <p className="text-sm text-od-muted">Aucune vidéo.</p>}
        </div>
      )}
    </div>
  );
}

// ── Users tab ────────────────────────────────────────────────────────────────

function UsersTab() {
  const [users, setUsers] = useState<AdminUser[]>([]);
  const [plans, setPlans] = useState<Plan[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [actionError, setActionError] = useState<string | null>(null);
  const [assigning, setAssigning] = useState<string | null>(null);
  const [selectedPlan, setSelectedPlan] = useState<Record<string, string>>({});
  const [assigningRole, setAssigningRole] = useState<string | null>(null);
  const [selectedRole, setSelectedRole] = useState<Record<string, string>>({});

  useEffect(() => {
    Promise.all([
      apiFetch<{ success: boolean; data: { users: AdminUser[] } }>('/admin/users'),
      apiFetch<{ success: boolean; data: { plans: Plan[] } }>('/admin/plans'),
    ])
      .then(([ur, pr]) => {
        setUsers(ur.data.users);
        setPlans(pr.data.plans);
      })
      .catch(() => setError('Impossible de charger les utilisateurs.'))
      .finally(() => setLoading(false));
  }, []);

  async function assignPlan(userId: string) {
    const planId = selectedPlan[userId];
    if (!planId || assigning) return;
    setAssigning(userId);
    setActionError(null);
    try {
      await apiFetch(`/admin/users/${userId}/subscriptions`, {
        method: 'POST',
        body: JSON.stringify({ planId }),
      });
      const r = await apiFetch<{ success: boolean; data: { users: AdminUser[] } }>('/admin/users');
      setUsers(r.data.users);
    } catch {
      setActionError('Impossible d\'assigner le plan.');
    }
    setAssigning(null);
  }

  async function assignRole(userId: string) {
    const role = selectedRole[userId];
    if (!role || assigningRole) return;
    setAssigningRole(userId);
    setActionError(null);
    try {
      await apiFetch(`/admin/users/${userId}/roles`, {
        method: 'PATCH',
        body: JSON.stringify({ roles: [role] }),
      });
      const r = await apiFetch<{ success: boolean; data: { users: AdminUser[] } }>('/admin/users');
      setUsers(r.data.users);
    } catch {
      setActionError('Impossible d\'assigner le rôle.');
    }
    setAssigningRole(null);
  }

  if (loading) return (
    <div className="flex flex-col gap-2">
      {[...Array(3)].map((_, i) => <div key={i} className="h-20 rounded border border-od-border animate-pulse" />)}
    </div>
  );

  if (error) return <p className="text-sm text-od-crit">{error}</p>;

  return (
    <div className="flex flex-col gap-2">
      {actionError && <p className="text-xs text-od-crit">{actionError}</p>}
      {users.map((u) => (
        <div key={u.id} className="flex flex-col gap-2 rounded border border-od-border bg-od-surface px-4 py-3">
          <div className="flex items-start justify-between gap-2">
            <div>
              <p className="text-sm font-medium text-od-text">{u.nickname}</p>
              <p className="font-mono text-xs text-od-muted">{u.email ?? '—'}</p>
            </div>
            <div className="flex flex-col items-end gap-1">
              <span className="font-mono text-xs text-od-muted">
                {u.roles.map((r) => r.slug).join(', ') || '—'}
              </span>
              {u.activeSubscription ? (
                <span className="font-mono text-xs text-od-accent">
                  {u.activeSubscription.plan.name}
                  {u.activeSubscription.endsAt && ` · ${new Date(u.activeSubscription.endsAt).toLocaleDateString()}`}
                </span>
              ) : (
                <span className="font-mono text-xs text-od-muted">free</span>
              )}
            </div>
          </div>

          <div className="flex items-center gap-2">
            <select
              value={selectedPlan[u.id] ?? ''}
              onChange={(e) => setSelectedPlan((s) => ({ ...s, [u.id]: e.target.value }))}
              className="flex-1 rounded border border-od-border bg-od-bg px-2 py-1 text-xs text-od-text outline-none focus:border-od-accent"
            >
              <option value="">— Plan —</option>
              {plans.filter((p) => p.isActive).map((p) => (
                <option key={p.id} value={p.id}>{p.name} (niv. {p.level})</option>
              ))}
            </select>
            <button
              disabled={!selectedPlan[u.id] || assigning === u.id}
              onClick={() => assignPlan(u.id)}
              className="rounded border border-od-border px-3 py-1 font-mono text-xs text-od-muted hover:border-od-accent hover:text-od-accent transition-colors disabled:opacity-40"
            >
              {assigning === u.id ? '…' : 'Plan'}
            </button>
            <select
              value={selectedRole[u.id] ?? ''}
              onChange={(e) => setSelectedRole((s) => ({ ...s, [u.id]: e.target.value }))}
              className="rounded border border-od-border bg-od-bg px-2 py-1 text-xs text-od-text outline-none focus:border-od-accent"
            >
              <option value="">— Rôle —</option>
              <option value="user">user</option>
              <option value="admin">admin</option>
              <option value="super_admin">super_admin</option>
            </select>
            <button
              disabled={!selectedRole[u.id] || assigningRole === u.id}
              onClick={() => assignRole(u.id)}
              className="rounded border border-od-border px-3 py-1 font-mono text-xs text-od-muted hover:border-od-accent hover:text-od-accent transition-colors disabled:opacity-40"
            >
              {assigningRole === u.id ? '…' : 'Rôle'}
            </button>
          </div>
        </div>
      ))}
      {users.length === 0 && <p className="text-sm text-od-muted">Aucun utilisateur.</p>}
    </div>
  );
}

// ── Plans tab ─────────────────────────────────────────────────────────────────

function PlansTab() {
  const [plans, setPlans] = useState<Plan[]>([]);
  const [loading, setLoading] = useState(true);
  const [fetchError, setFetchError] = useState<string | null>(null);
  const [actionError, setActionError] = useState<string | null>(null);
  const [form, setForm] = useState({ slug: '', name: '', level: 1, priceInCents: 0 });
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    apiFetch<{ success: boolean; data: { plans: Plan[] } }>('/admin/plans')
      .then((r) => setPlans(r.data.plans))
      .catch(() => setFetchError('Impossible de charger les plans.'))
      .finally(() => setLoading(false));
  }, []);

  async function handleCreate(e: React.FormEvent) {
    e.preventDefault();
    if (!form.slug || !form.name || saving) return;
    setSaving(true);
    setError(null);
    try {
      const r = await apiFetch<{ success: boolean; data: { plan: Plan } }>(
        '/admin/plans',
        { method: 'POST', body: JSON.stringify(form) }
      );
      setPlans((p) => [...p, r.data.plan]);
      setForm({ slug: '', name: '', level: 1, priceInCents: 0 });
    } catch {
      setError('Erreur lors de la création.');
    }
    setSaving(false);
  }

  async function toggleActive(plan: Plan) {
    setActionError(null);
    try {
      const r = await apiFetch<{ success: boolean; data: { plan: Plan } }>(
        `/admin/plans/${plan.id}`,
        { method: 'PATCH', body: JSON.stringify({ isActive: !plan.isActive }) }
      );
      setPlans((p) => p.map((x) => x.id === plan.id ? r.data.plan : x));
    } catch {
      setActionError('Impossible de modifier le plan.');
    }
  }

  if (loading) return (
    <div className="flex flex-col gap-2">
      {[...Array(2)].map((_, i) => <div key={i} className="h-12 rounded border border-od-border animate-pulse" />)}
    </div>
  );

  if (fetchError) return <p className="text-sm text-od-crit">{fetchError}</p>;

  return (
    <div className="flex flex-col gap-6">

      <form onSubmit={handleCreate} className="flex flex-col gap-3 rounded border border-od-border bg-od-surface p-4">
        <p className="font-mono text-xs text-od-muted uppercase tracking-widest">Nouveau plan</p>
        <div className="flex gap-2">
          <input
            value={form.slug}
            onChange={(e) => setForm((f) => ({ ...f, slug: e.target.value }))}
            placeholder="slug (ex: premium)"
            required
            className="flex-1 rounded border border-od-border bg-od-bg px-3 py-2 text-sm text-od-text placeholder-od-muted outline-none focus:border-od-accent"
          />
          <input
            value={form.name}
            onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}
            placeholder="Nom"
            required
            className="flex-1 rounded border border-od-border bg-od-bg px-3 py-2 text-sm text-od-text placeholder-od-muted outline-none focus:border-od-accent"
          />
        </div>
        <div className="flex gap-2">
          <label className="flex items-center gap-2 text-sm text-od-muted">
            Niveau
            <input
              type="number" min={1}
              value={form.level}
              onChange={(e) => setForm((f) => ({ ...f, level: parseInt(e.target.value) || 1 }))}
              className="w-16 rounded border border-od-border bg-od-bg px-2 py-1 text-sm text-od-text outline-none focus:border-od-accent"
            />
          </label>
          <label className="flex items-center gap-2 text-sm text-od-muted">
            Prix (centimes)
            <input
              type="number" min={0}
              value={form.priceInCents}
              onChange={(e) => setForm((f) => ({ ...f, priceInCents: parseInt(e.target.value) || 0 }))}
              className="w-24 rounded border border-od-border bg-od-bg px-2 py-1 text-sm text-od-text outline-none focus:border-od-accent"
            />
          </label>
        </div>
        {error && <p className="text-xs text-od-crit">{error}</p>}
        <button
          type="submit" disabled={saving}
          className="self-start rounded border border-od-accent px-4 py-1.5 font-mono text-xs text-od-accent hover:bg-od-accent hover:text-od-bg transition-colors disabled:opacity-40"
        >
          {saving ? '…' : 'Créer'}
        </button>
      </form>

      <div className="flex flex-col gap-2">
        {actionError && <p className="text-xs text-od-crit">{actionError}</p>}
        {plans.map((p) => (
          <div key={p.id} className="flex items-center gap-3 rounded border border-od-border bg-od-surface px-4 py-3">
            <div className="flex-1">
              <p className="text-sm text-od-text">{p.name}</p>
              <p className="font-mono text-xs text-od-muted">
                {p.slug} · niv. {p.level} · {(p.priceInCents / 100).toFixed(2)} €
              </p>
            </div>
            <button
              onClick={() => toggleActive(p)}
              className={`font-mono text-xs px-2 py-0.5 rounded border transition-colors ${
                p.isActive
                  ? 'border-od-accent text-od-accent hover:bg-od-accent hover:text-od-bg'
                  : 'border-od-border text-od-muted hover:border-od-accent hover:text-od-accent'
              }`}
            >
              {p.isActive ? 'actif' : 'inactif'}
            </button>
          </div>
        ))}
        {plans.length === 0 && <p className="text-sm text-od-muted">Aucun plan.</p>}
      </div>
    </div>
  );
}
