import { useState, useEffect, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '@persona-community-5/auth';
import { useEventChannel, type ChannelEvent } from '@persona-community-5/realtime';
import {
  Button,
  Badge,
  Textarea,
  Input,
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetDescription,
  Plus,
  ImageIcon,
  Video,
  Loader2,
} from '@persona-community-5/ui';

interface Persona {
  id: string;
  name: string;
  handle: string;
  gender: string;
  description: string;
  tags: string[];
  anchor_url?: string;
  avatar_url?: string;
  banner_url?: string;
  image_urls: string[];
  video_urls: string[];
  status: string;
  created_at: string;
}

const STAGE_LABELS: Record<string, string> = {
  spec: 'Crafting identity...',
  anchor: 'Generating anchor...',
  avatar: 'Creating avatar...',
  banner: 'Designing banner...',
  gallery_batch: 'Generating gallery...',
  video: 'Producing videos...',
};

type Gender = 'woman' | 'man' | 'non_binary';

const GENDER_OPTIONS: { value: Gender; label: string }[] = [
  { value: 'woman', label: 'Female' },
  { value: 'man', label: 'Male' },
  { value: 'non_binary', label: 'Non-binary' },
];

function PersonaCard({
  persona,
  stage,
  onClick,
}: {
  persona: Persona;
  stage?: string;
  onClick: () => void;
}) {
  const isGenerating = persona.status === 'pending' || persona.status === 'generating';
  const tags = persona.tags?.slice(0, 4) ?? [];

  return (
    <button
      type="button"
      onClick={onClick}
      className="group relative rounded-xl overflow-hidden border border-[var(--border-muted)] bg-[var(--surface-100)] text-left transition-all hover:border-[var(--border-hover)] hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-[var(--accent)]"
    >
      {/* Banner */}
      <div className="relative h-40 bg-[var(--surface-200)]">
        {persona.banner_url && (
          <img
            src={persona.banner_url}
            alt=""
            className="h-full w-full object-cover"
          />
        )}

        {/* Generating overlay */}
        {isGenerating && (
          <div className="absolute inset-0 bg-black/50 flex items-center justify-center">
            <div className="flex flex-col items-center gap-2">
              <div className="h-6 w-6 rounded-full border-2 border-[var(--accent)] border-t-transparent animate-spin" />
              <span className="text-xs text-white/80">
                {stage ? STAGE_LABELS[stage] || stage : 'Generating...'}
              </span>
            </div>
          </div>
        )}

        {/* Avatar overlay */}
        <div className="absolute -bottom-5 left-4">
          <div className="h-12 w-12 rounded-full border-2 border-[var(--background)] bg-[var(--surface-300)] overflow-hidden">
            {persona.avatar_url ? (
              <img
                src={persona.avatar_url}
                alt={persona.name}
                className="h-full w-full object-cover"
              />
            ) : (
              <div className="h-full w-full flex items-center justify-center text-[var(--text-muted)] text-sm font-medium">
                {persona.name?.charAt(0)?.toUpperCase() || '?'}
              </div>
            )}
          </div>
        </div>
      </div>

      {/* Content */}
      <div className="p-4 pt-7">
        <h3 className="text-sm font-semibold text-[var(--text-primary)] truncate">
          {persona.name}
        </h3>
        <p className="text-xs text-[var(--text-muted)] truncate">@{persona.handle}</p>

        {/* Tags */}
        {tags.length > 0 && (
          <div className="mt-2 flex flex-wrap gap-1">
            {tags.map((tag) => (
              <Badge key={tag} variant="secondary" className="text-[10px] px-1.5 py-0">
                {tag}
              </Badge>
            ))}
          </div>
        )}

        {/* Media badges */}
        <div className="mt-3 flex items-center gap-3 text-xs text-[var(--text-muted)]">
          {persona.image_urls?.length > 0 && (
            <span className="flex items-center gap-1">
              <ImageIcon className="h-3 w-3" />
              {persona.image_urls.length}
            </span>
          )}
          {persona.video_urls?.length > 0 && (
            <span className="flex items-center gap-1">
              <Video className="h-3 w-3" />
              {persona.video_urls.length}
            </span>
          )}
        </div>
      </div>
    </button>
  );
}

export function CommunityPage() {
  const navigate = useNavigate();
  const { getToken } = useAuth();
  const [personas, setPersonas] = useState<Persona[]>([]);
  const [loading, setLoading] = useState(true);
  const [createOpen, setCreateOpen] = useState(false);
  const [creating, setCreating] = useState(false);
  const [description, setDescription] = useState('');
  const [gender, setGender] = useState<Gender>('woman');
  const [customName, setCustomName] = useState('');
  const [createError, setCreateError] = useState<string | null>(null);
  const [stages, setStages] = useState<Record<string, string>>({});

  const apiBaseUrl = import.meta.env.VITE_API_URL || '';

  const fetchPersonas = useCallback(async () => {
    try {
      const token = await getToken();
      const res = await fetch(`${apiBaseUrl}/api/persona-api/personas?limit=100`, {
        headers: token ? { Authorization: `Bearer ${token}` } : {},
      });
      if (!res.ok) throw new Error('Failed to load personas');
      const json = await res.json();
      setPersonas(json.data ?? []);
    } catch {
      // silent
    } finally {
      setLoading(false);
    }
  }, [apiBaseUrl, getToken]);

  useEffect(() => {
    fetchPersonas();
  }, [fetchPersonas]);

  // Realtime: subscribe to channel:personas
  const handleEvent = useCallback(
    (event: ChannelEvent) => {
      if (event.type === 'persona_updated') {
        const updated = event.persona as Persona | undefined;
        if (updated) {
          setPersonas((prev) => {
            const idx = prev.findIndex((p) => p.id === updated.id);
            if (idx >= 0) {
              const next = [...prev];
              next[idx] = updated;
              return next;
            }
            return [updated, ...prev];
          });
        } else {
          // Refetch if we don't have inline data
          fetchPersonas();
        }
      }
      if (event.type === 'job_update') {
        const personaId = event.persona_id as string | undefined;
        const stage = event.stage as string | undefined;
        if (personaId && stage) {
          setStages((prev) => ({ ...prev, [personaId]: stage }));
        }
      }
    },
    [fetchPersonas]
  );

  useEventChannel({
    endpoint: `${apiBaseUrl}/api/persona-api/events`,
    channel: 'channel:personas',
    onEvent: handleEvent,
  });

  const handleCreate = async (e: React.FormEvent) => {
    e.preventDefault();
    setCreateError(null);
    setCreating(true);

    try {
      const token = await getToken();
      const res = await fetch(`${apiBaseUrl}/api/persona-api/personas`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({
          description,
          gender,
          custom_name: customName || undefined,
        }),
      });

      if (!res.ok) {
        const json = await res.json().catch(() => null);
        throw new Error(json?.error?.message || 'Failed to create persona');
      }

      const json = await res.json();
      const newPersona = json.data as Persona;

      // Add immediately with generating state
      setPersonas((prev) => [newPersona, ...prev]);
      setCreateOpen(false);
      setDescription('');
      setCustomName('');
      setGender('woman');
    } catch (err) {
      setCreateError(err instanceof Error ? err.message : 'Failed to create persona');
    } finally {
      setCreating(false);
    }
  };

  return (
    <div className="space-y-6">
      {/* Top bar */}
      <div className="flex items-center justify-between">
        <h2 className="text-lg font-semibold text-[var(--text-primary)]">Personas</h2>
        <Button onClick={() => setCreateOpen(true)}>
          <Plus className="mr-2 h-4 w-4" />
          Create Persona
        </Button>
      </div>

      {/* Grid */}
      {loading ? (
        <div className="flex items-center justify-center py-20">
          <Loader2 className="h-8 w-8 animate-spin text-[var(--accent)]" />
        </div>
      ) : personas.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-20 text-[var(--text-muted)]">
          <p className="text-sm">No personas yet. Create your first one!</p>
        </div>
      ) : (
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
          {personas.map((persona) => (
            <PersonaCard
              key={persona.id}
              persona={persona}
              stage={stages[persona.id]}
              onClick={() => navigate(`/personas/${persona.id}`)}
            />
          ))}
        </div>
      )}

      {/* Create Panel (Sheet sliding from right) */}
      <Sheet open={createOpen} onOpenChange={setCreateOpen}>
        <SheetContent side="right" className="overflow-y-auto">
          <SheetHeader>
            <SheetTitle>Create Persona</SheetTitle>
            <SheetDescription>Describe a new AI persona to generate.</SheetDescription>
          </SheetHeader>

          <form onSubmit={handleCreate} className="mt-6 space-y-5">
            {/* Description */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-[var(--text-primary)]">
                Description
              </label>
              <Textarea
                placeholder="Describe your persona..."
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                required
                rows={4}
                className="resize-none"
              />
            </div>

            {/* Gender pills */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-[var(--text-primary)]">
                Gender
              </label>
              <div className="flex gap-2">
                {GENDER_OPTIONS.map((opt) => (
                  <button
                    key={opt.value}
                    type="button"
                    onClick={() => setGender(opt.value)}
                    className={`px-3 py-1.5 text-sm rounded-full border transition-colors ${
                      gender === opt.value
                        ? 'bg-[var(--accent)] text-[var(--accent-foreground)] border-[var(--accent)]'
                        : 'bg-[var(--surface-100)] text-[var(--text-secondary)] border-[var(--border)] hover:border-[var(--border-hover)]'
                    }`}
                  >
                    {opt.label}
                  </button>
                ))}
              </div>
            </div>

            {/* Optional Name */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-[var(--text-primary)]">
                Name <span className="text-[var(--text-muted)] font-normal">(optional)</span>
              </label>
              <Input
                placeholder="Auto-generated if empty"
                value={customName}
                onChange={(e) => setCustomName(e.target.value)}
              />
            </div>

            {createError && (
              <p className="text-sm text-[var(--error)]">{createError}</p>
            )}

            <Button type="submit" className="w-full" disabled={creating || !description.trim()}>
              {creating && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              Create
            </Button>
          </form>
        </SheetContent>
      </Sheet>
    </div>
  );
}
