import { useState, useEffect, useCallback } from 'react';
import { router, useForm } from '@inertiajs/react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
    Dialog,
    DialogContent,
    DialogHeader,
    DialogTitle,
    DialogFooter,
    DialogClose,
} from '@/components/ui/dialog';
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { StickyNoteIcon, PlusIcon, PencilIcon, Trash2Icon, Loader2Icon, CheckCircle2Icon } from 'lucide-react';
import { toast } from 'sonner';
import { Note, AudioStatus } from '@/types';
import { RichTextEditor } from '@/components/rich-text-editor';
import { ContentAudioPlayer } from '@/components/content-audio-player';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import remarkBreaks from 'remark-breaks';
import rehypeRaw from 'rehype-raw';

interface NotesSectionProps {
    notableType: 'project' | 'document' | 'video';
    notableId: number;
    notes: Note[];
}

export function NotesSection({ notableType, notableId, notes: initialNotes }: NotesSectionProps) {
    const [isAddOpen, setIsAddOpen] = useState(false);
    const [editNote, setEditNote] = useState<Note | null>(null);
    const [deleteNote, setDeleteNote] = useState<Note | null>(null);

    // Local state to track notes with their audio status
    const [localNotes, setLocalNotes] = useState<Note[]>(initialNotes);

    // Sync with props when they change (e.g., after Inertia navigation)
    useEffect(() => {
        setLocalNotes(initialNotes);
    }, [initialNotes]);

    // Poll for audio status updates when any note is generating
    useEffect(() => {
        const generatingNotes = localNotes.filter(n => n.audio_status === 'generating');
        if (generatingNotes.length === 0) return;

        const pollInterval = setInterval(async () => {
            try {
                // Fetch status for all generating notes
                const statusPromises = generatingNotes.map(async (note) => {
                    const response = await fetch(`/api/notes/${note.id}/audio-status`, {
                        headers: { 'X-Requested-With': 'XMLHttpRequest' },
                    });
                    const result = await response.json();
                    return { noteId: note.id, ...result.data };
                });

                const statuses = await Promise.all(statusPromises);

                setLocalNotes(prev => prev.map(note => {
                    const status = statuses.find(s => s.noteId === note.id);
                    if (status) {
                        return {
                            ...note,
                            audio_status: status.audio_status,
                            audio_path: status.audio_path,
                            updated_at: status.updated_at,
                        };
                    }
                    return note;
                }));
            } catch (error) {
                console.error('Failed to poll audio status:', error);
            }
        }, 3000);

        return () => clearInterval(pollInterval);
    }, [localNotes]);

    const addForm = useForm({
        content: '',
        notable_type: notableType,
        notable_id: notableId,
    });

    const editForm = useForm({ content: '' });

    const handleAdd = (e: React.FormEvent) => {
        e.preventDefault();
        addForm.post('/notes', {
            onSuccess: () => {
                toast.success('Note added');
                addForm.reset();
                setIsAddOpen(false);
            },
            onError: () => toast.error('Failed to add note'),
        });
    };

    const handleEdit = (e: React.FormEvent) => {
        e.preventDefault();
        if (!editNote) return;
        editForm.put(`/notes/${editNote.id}`, {
            onSuccess: () => {
                toast.success('Note updated');
                setEditNote(null);
            },
            onError: () => toast.error('Failed to update note'),
        });
    };

    const handleDelete = () => {
        if (!deleteNote) return;
        router.delete(`/notes/${deleteNote.id}`, {
            onSuccess: () => {
                toast.success('Note deleted');
                setDeleteNote(null);
            },
            onError: () => toast.error('Failed to delete note'),
        });
    };

    const openEdit = (note: Note) => {
        editForm.setData('content', note.content);
        setEditNote(note);
    };

    const formatDate = (dateString: string) => {
        return new Date(dateString).toLocaleDateString('en-US', {
            month: 'short',
            day: 'numeric',
            hour: '2-digit',
            minute: '2-digit',
        });
    };

    const generateNoteAudio = useCallback(async (noteId: number) => {
        // Optimistically update UI to show generating status
        setLocalNotes(prev => prev.map(note =>
            note.id === noteId ? { ...note, audio_status: 'generating' as AudioStatus } : note
        ));

        try {
            const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
            const response = await fetch(`/api/notes/${noteId}/generate-audio`, {
                method: 'POST',
                headers: {
                    'X-CSRF-TOKEN': csrfToken || '',
                    'X-Requested-With': 'XMLHttpRequest',
                },
            });
            const result = await response.json();
            if (result.error !== 0) {
                // Revert on error
                setLocalNotes(prev => prev.map(note =>
                    note.id === noteId ? { ...note, audio_status: null } : note
                ));
                throw new Error(result.message);
            }
        } catch (error) {
            setLocalNotes(prev => prev.map(note =>
                note.id === noteId ? { ...note, audio_status: null } : note
            ));
            throw error;
        }
    }, []);

    const regenerateNoteAudio = useCallback(async (noteId: number) => {
        // Optimistically update UI to show generating status
        setLocalNotes(prev => prev.map(note =>
            note.id === noteId ? { ...note, audio_status: 'generating' as AudioStatus, audio_path: null } : note
        ));

        try {
            const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
            const response = await fetch(`/api/notes/${noteId}/regenerate-audio`, {
                method: 'POST',
                headers: {
                    'X-CSRF-TOKEN': csrfToken || '',
                    'X-Requested-With': 'XMLHttpRequest',
                },
            });
            const result = await response.json();
            if (result.error !== 0) {
                // Revert on error
                setLocalNotes(prev => prev.map(note =>
                    note.id === noteId ? { ...note, audio_status: 'completed' as AudioStatus } : note
                ));
                throw new Error(result.message);
            }
        } catch (error) {
            setLocalNotes(prev => prev.map(note =>
                note.id === noteId ? { ...note, audio_status: 'completed' as AudioStatus } : note
            ));
            throw error;
        }
    }, []);

    return (
        <Card>
            <CardHeader className="pb-3">
                <div className="flex items-center justify-between">
                    <div className="flex items-center gap-2">
                        <StickyNoteIcon className="h-5 w-5 text-primary" />
                        <CardTitle className="text-lg">Notes</CardTitle>
                    </div>
                    <Button size="sm" onClick={() => setIsAddOpen(true)}>
                        <PlusIcon className="mr-1 h-4 w-4" />
                        Add Note
                    </Button>
                </div>
            </CardHeader>
            <CardContent>
                {localNotes.length === 0 ? (
                    <p className="py-4 text-center text-sm text-muted-foreground">
                        No notes yet. Add notes to enhance AI search context.
                    </p>
                ) : (
                    <div className="space-y-3">
                        {localNotes.map((note) => (
                            <div key={note.id} className="group rounded-lg border bg-muted/30 p-3">
                                <div className="prose prose-sm dark:prose-invert max-w-none prose-p:my-1 prose-headings:my-2 prose-ul:my-1 prose-ol:my-1 prose-li:my-0">
                                    <ReactMarkdown remarkPlugins={[remarkGfm, remarkBreaks]} rehypePlugins={[rehypeRaw]}>
                                        {note.content}
                                    </ReactMarkdown>
                                </div>
                                {/* Compact footer: audio + metadata + actions */}
                                <div className="mt-3 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                                    {/* Audio player - compact */}
                                    <div className="flex-1 min-w-0">
                                        <ContentAudioPlayer
                                            audioUrl={note.audio_path ? `/notes/${note.id}/audio?v=${new Date(note.updated_at).getTime()}` : undefined}
                                            audioStatus={note.audio_status}
                                            onGenerate={() => generateNoteAudio(note.id)}
                                            onRegenerate={() => regenerateNoteAudio(note.id)}
                                            compact
                                        />
                                    </div>
                                    {/* Metadata + actions */}
                                    <div className="flex items-center justify-between gap-2 sm:justify-end">
                                        <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
                                            <span className="truncate max-w-[150px]">{note.user_name}</span>
                                            <span>&middot;</span>
                                            <span className="whitespace-nowrap">{formatDate(note.created_at)}</span>
                                            {note.vector_indexed_at ? (
                                                <span className="text-green-600 dark:text-green-400" title="Indexed for search">
                                                    <CheckCircle2Icon className="h-3 w-3" />
                                                </span>
                                            ) : (
                                                <span className="text-blue-600 dark:text-blue-400" title="Indexing...">
                                                    <Loader2Icon className="h-3 w-3 animate-spin" />
                                                </span>
                                            )}
                                        </div>
                                        <div className="flex gap-0.5 opacity-0 transition-opacity group-hover:opacity-100 sm:ml-2">
                                            <Button
                                                variant="ghost"
                                                size="icon"
                                                className="h-6 w-6"
                                                onClick={() => openEdit(note)}
                                            >
                                                <PencilIcon className="h-3 w-3" />
                                            </Button>
                                            <Button
                                                variant="ghost"
                                                size="icon"
                                                className="h-6 w-6 text-destructive"
                                                onClick={() => setDeleteNote(note)}
                                            >
                                                <Trash2Icon className="h-3 w-3" />
                                            </Button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        ))}
                    </div>
                )}
            </CardContent>

            {/* Add Dialog */}
            <Dialog open={isAddOpen} onOpenChange={setIsAddOpen}>
                <DialogContent className="sm:max-w-2xl">
                    <DialogHeader>
                        <DialogTitle>Add Note</DialogTitle>
                    </DialogHeader>
                    <form onSubmit={handleAdd} className="space-y-4">
                        <RichTextEditor
                            defaultValue=""
                            onChange={(markdown) => addForm.setData('content', markdown)}
                            placeholder="Write your note..."
                        />
                        <DialogFooter>
                            <DialogClose asChild>
                                <Button type="button" variant="outline">
                                    Cancel
                                </Button>
                            </DialogClose>
                            <Button type="submit" disabled={addForm.processing || !addForm.data.content.trim()}>
                                {addForm.processing && <Loader2Icon className="mr-2 h-4 w-4 animate-spin" />}
                                Save Note
                            </Button>
                        </DialogFooter>
                    </form>
                </DialogContent>
            </Dialog>

            {/* Edit Dialog */}
            <Dialog open={!!editNote} onOpenChange={(open) => !open && setEditNote(null)}>
                <DialogContent className="sm:max-w-2xl">
                    <DialogHeader>
                        <DialogTitle>Edit Note</DialogTitle>
                    </DialogHeader>
                    <form onSubmit={handleEdit} className="space-y-4">
                        {editNote && (
                            <RichTextEditor
                                key={editNote.id}
                                defaultValue={editNote.content}
                                onChange={(markdown) => editForm.setData('content', markdown)}
                                placeholder="Write your note..."
                            />
                        )}
                        <DialogFooter>
                            <DialogClose asChild>
                                <Button type="button" variant="outline">
                                    Cancel
                                </Button>
                            </DialogClose>
                            <Button type="submit" disabled={editForm.processing || !editForm.data.content.trim()}>
                                {editForm.processing && <Loader2Icon className="mr-2 h-4 w-4 animate-spin" />}
                                Update Note
                            </Button>
                        </DialogFooter>
                    </form>
                </DialogContent>
            </Dialog>

            {/* Delete Confirmation */}
            <AlertDialog open={!!deleteNote} onOpenChange={(open) => !open && setDeleteNote(null)}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>Delete Note</AlertDialogTitle>
                        <AlertDialogDescription>
                            Are you sure you want to delete this note? This action cannot be undone.
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel>Cancel</AlertDialogCancel>
                        <AlertDialogAction
                            onClick={handleDelete}
                            className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
                        >
                            Delete
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </Card>
    );
}
