import { useState, useEffect, useRef, useCallback } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/contexts/AuthContext";
import { useToast } from "@/hooks/use-toast";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import { ArrowLeft, Lock, Unlock, Save, Clock, User } from "lucide-react";
import { format } from "date-fns";
import ReactQuill from "react-quill-new";
import "react-quill-new/dist/quill.snow.css";

// Assign a consistent color to each user
const MEMBER_COLORS = [
  "#3b82f6", "#ef4444", "#22c55e", "#f59e0b", "#8b5cf6",
  "#ec4899", "#06b6d4", "#f97316", "#6366f1", "#14b8a6",
];

interface Props {
  document: any;
  onBack: () => void;
  associations: any[];
}

export default function CollaborativeDocumentEditor({ document: doc, onBack, associations }: Props) {
  const { user } = useAuth();
  const { toast } = useToast();
  const [content, setContent] = useState(doc.content || "");
  const [editHistory, setEditHistory] = useState<any[]>([]);
  const [isLocked, setIsLocked] = useState(false);
  const [lockedByName, setLockedByName] = useState("");
  const [isMyLock, setIsMyLock] = useState(false);
  const [saving, setSaving] = useState(false);
  const [userProfile, setUserProfile] = useState<any>(null);
  const [userColorMap, setUserColorMap] = useState<Record<string, string>>({});
  const quillRef = useRef<any>(null);

  useEffect(() => {
    fetchLatestDoc();
    fetchEditHistory();
    fetchUserProfile();
    const channel = supabase
      .channel(`collab-doc-${doc.id}`)
      .on("postgres_changes", { event: "*", schema: "public", table: "collaborative_documents", filter: `id=eq.${doc.id}` }, () => fetchLatestDoc())
      .on("postgres_changes", { event: "INSERT", schema: "public", table: "document_edit_history", filter: `document_id=eq.${doc.id}` }, () => fetchEditHistory())
      .subscribe();
    return () => { supabase.removeChannel(channel); };
  }, [doc.id]);

  const fetchUserProfile = async () => {
    if (!user) return;
    const { data } = await supabase.from("profiles").select("full_name").eq("user_id", user.id).maybeSingle();
    setUserProfile(data);
  };

  const fetchLatestDoc = async () => {
    const { data } = await supabase.from("collaborative_documents").select("*").eq("id", doc.id).single();
    if (data) {
      if (!isMyLock) setContent(data.content || "");
      setIsLocked(!!data.locked_by);
      setIsMyLock(data.locked_by === user?.id);
      if (data.locked_by && data.locked_by !== user?.id) {
        const { data: profile } = await supabase.from("profiles").select("full_name").eq("user_id", data.locked_by).maybeSingle();
        setLockedByName(profile?.full_name || "Another member");
      } else {
        setLockedByName("");
      }
    }
  };

  const fetchEditHistory = async () => {
    const { data } = await supabase
      .from("document_edit_history")
      .select("*")
      .eq("document_id", doc.id)
      .order("created_at", { ascending: false })
      .limit(50);
    if (data) {
      setEditHistory(data);
      // Build color map from unique users
      const map: Record<string, string> = {};
      const uniqueUsers = [...new Set(data.map((e) => e.user_id))];
      uniqueUsers.forEach((uid, i) => {
        map[uid] = MEMBER_COLORS[i % MEMBER_COLORS.length];
      });
      setUserColorMap(map);
    }
  };

  const acquireLock = async () => {
    // Check if already locked by someone else
    const { data: current } = await supabase.from("collaborative_documents").select("locked_by, locked_at, content").eq("id", doc.id).single();
    if (current?.locked_by && current.locked_by !== user?.id) {
      // Check if lock is stale (>15 min)
      const lockedAt = new Date(current.locked_at).getTime();
      if (Date.now() - lockedAt < 15 * 60 * 1000) {
        toast({ title: "Document is locked", description: "Another board member is currently editing.", variant: "destructive" });
        return;
      }
    }
    // Refresh content before locking
    if (current) setContent(current.content || "");
    const { error } = await supabase.from("collaborative_documents").update({ locked_by: user?.id, locked_at: new Date().toISOString() }).eq("id", doc.id);
    if (error) toast({ title: "Error", description: error.message, variant: "destructive" });
    else {
      setIsLocked(true);
      setIsMyLock(true);
    }
  };

  const releaseLock = async (silent?: boolean) => {
    const { error } = await supabase.from("collaborative_documents").update({ locked_by: null, locked_at: null }).eq("id", doc.id);
    if (error && !silent) toast({ title: "Error", description: error.message, variant: "destructive" });
    setIsLocked(false);
    setIsMyLock(false);
  };

  const handleSave = async () => {
    if (!isMyLock) return;
    setSaving(true);
    const userName = userProfile?.full_name || user?.email || "Unknown";
    const { error: updateErr } = await supabase.from("collaborative_documents").update({ content, updated_at: new Date().toISOString() }).eq("id", doc.id);
    if (updateErr) {
      toast({ title: "Error saving", description: updateErr.message, variant: "destructive" });
      setSaving(false);
      return;
    }
    // Log edit
    const color = userColorMap[user?.id || ""] || MEMBER_COLORS[0];
    await supabase.from("document_edit_history").insert({
      document_id: doc.id,
      user_id: user?.id,
      user_name: userName,
      user_color: color,
      change_summary: "Edited the document",
      content_snapshot: content.substring(0, 500),
    });
    toast({ title: "Saved successfully" });
    setSaving(false);
  };

  const handleSaveAndRelease = async () => {
    await handleSave();
    await releaseLock();
  };

  const assocName = associations.find((a) => a.id === doc.association_id)?.name || "";

  const quillModules = {
    toolbar: [
      [{ header: [1, 2, 3, false] }],
      ["bold", "italic", "underline", "strike"],
      [{ color: [] }, { background: [] }],
      [{ list: "ordered" }, { list: "bullet" }],
      [{ align: [] }],
      ["blockquote", "code-block"],
      ["link"],
      ["clean"],
    ],
  };

  return (
    <div className="space-y-4">
      {/* Header */}
      <div className="flex items-center justify-between flex-wrap gap-3">
        <div className="flex items-center gap-3">
          <Button variant="ghost" size="icon" onClick={onBack}><ArrowLeft className="h-5 w-5" /></Button>
          <div>
            <h1 className="text-xl font-bold text-foreground">{doc.title}</h1>
            <p className="text-xs text-muted-foreground">{assocName}</p>
          </div>
        </div>
        <div className="flex items-center gap-2">
          {isLocked && !isMyLock && (
            <Badge variant="destructive" className="gap-1">
              <Lock className="h-3 w-3" /> Locked by {lockedByName}
            </Badge>
          )}
          {isMyLock && (
            <>
              <Badge variant="default" className="gap-1 bg-green-600">
                <Lock className="h-3 w-3" /> You are editing
              </Badge>
              <Button size="sm" onClick={handleSave} disabled={saving} className="gap-1">
                <Save className="h-4 w-4" /> Save
              </Button>
              <Button size="sm" variant="outline" onClick={handleSaveAndRelease} disabled={saving}>
                Save & Release
              </Button>
            </>
          )}
          {!isLocked && (
            <Button size="sm" onClick={acquireLock} className="gap-1">
              <Unlock className="h-4 w-4" /> Start Editing
            </Button>
          )}
        </div>
      </div>

      {/* Editor + History */}
      <div className="flex gap-4" style={{ minHeight: 500 }}>
        {/* Editor */}
        <div className="flex-1 min-w-0 border rounded-lg bg-card overflow-hidden">
          <ReactQuill
            ref={quillRef}
            theme="snow"
            value={content}
            onChange={setContent}
            readOnly={!isMyLock}
            modules={quillModules}
            className="h-full [&_.ql-container]:min-h-[420px] [&_.ql-editor]:min-h-[400px]"
          />
        </div>

        {/* Edit Log Sidebar */}
        <div className="w-[280px] shrink-0 border rounded-lg bg-card flex flex-col">
          <div className="px-4 py-3 border-b">
            <h3 className="text-sm font-bold flex items-center gap-2">
              <Clock className="h-4 w-4 text-muted-foreground" /> Edit Log
            </h3>
          </div>
          <ScrollArea className="flex-1">
            <div className="p-3 space-y-2">
              {editHistory.length === 0 ? (
                <p className="text-xs text-muted-foreground text-center py-6">No edits yet.</p>
              ) : (
                editHistory.map((entry) => (
                  <div key={entry.id} className="flex items-start gap-2 text-xs">
                    <div
                      className="w-2.5 h-2.5 rounded-full mt-1 shrink-0"
                      style={{ backgroundColor: entry.user_color || userColorMap[entry.user_id] || "#888" }}
                    />
                    <div className="min-w-0">
                      <p className="font-medium" style={{ color: entry.user_color || userColorMap[entry.user_id] || "inherit" }}>
                        {entry.user_name}
                      </p>
                      <p className="text-muted-foreground">{entry.change_summary}</p>
                      <p className="text-muted-foreground/70">{format(new Date(entry.created_at), "MMM d, h:mm a")}</p>
                    </div>
                  </div>
                ))
              )}
            </div>
          </ScrollArea>

          {/* Active members legend */}
          {Object.keys(userColorMap).length > 0 && (
            <div className="border-t px-4 py-3">
              <h4 className="text-xs font-bold text-muted-foreground mb-2">CONTRIBUTORS</h4>
              <div className="space-y-1">
                {editHistory
                  .reduce((acc: any[], e) => {
                    if (!acc.find((a: any) => a.user_id === e.user_id)) acc.push(e);
                    return acc;
                  }, [])
                  .map((e: any) => (
                    <div key={e.user_id} className="flex items-center gap-2 text-xs">
                      <div className="w-3 h-3 rounded-full" style={{ backgroundColor: e.user_color || userColorMap[e.user_id] }} />
                      <span>{e.user_name}</span>
                    </div>
                  ))}
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
