"use client";

import type { ReactElement } from "react";
import React, { useState, useEffect, useCallback } from "react";
import { useRouter, useParams } from "next/navigation";
import type { KnowledgeEntryWithTags, KnowledgeTag, KnowledgeBacklink } from "@mosaic/shared";
import { EntryStatus, Visibility } from "@mosaic/shared";
import { EntryViewer } from "@/components/knowledge/EntryViewer";
import { EntryEditor } from "@/components/knowledge/EntryEditor";
import { EntryMetadata } from "@/components/knowledge/EntryMetadata";
import { VersionHistory } from "@/components/knowledge/VersionHistory";
import { BacklinksList } from "@/components/knowledge/BacklinksList";
import {
  fetchEntry,
  updateEntry,
  deleteEntry,
  fetchTags,
  fetchBacklinks,
} from "@/lib/api/knowledge";

/**
 * Knowledge Entry Detail/Editor Page
 * View and edit mode for a single knowledge entry
 */
export default function EntryPage(): ReactElement {
  const router = useRouter();
  const params = useParams();
  const slug = params.slug as string;

  const [entry, setEntry] = useState<KnowledgeEntryWithTags | null>(null);
  const [isEditing, setIsEditing] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Backlinks state
  const [backlinks, setBacklinks] = useState<KnowledgeBacklink[]>([]);
  const [backlinksLoading, setBacklinksLoading] = useState(false);
  const [backlinksError, setBacklinksError] = useState<string | null>(null);

  // Edit state
  const [editTitle, setEditTitle] = useState("");
  const [editContent, setEditContent] = useState("");
  const [editStatus, setEditStatus] = useState<EntryStatus>(EntryStatus.DRAFT);
  const [editVisibility, setEditVisibility] = useState<Visibility>(Visibility.WORKSPACE);
  const [editTags, setEditTags] = useState<string[]>([]);
  const [availableTags, setAvailableTags] = useState<KnowledgeTag[]>([]);
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
  const [activeTab, setActiveTab] = useState<"content" | "history">("content");

  // Load entry data
  useEffect(() => {
    async function loadEntry(): Promise<void> {
      try {
        setIsLoading(true);
        const data = await fetchEntry(slug);
        setEntry(data);
        setEditTitle(data.title);
        setEditContent(data.content);
        setEditStatus(data.status);
        setEditVisibility(data.visibility);
        setEditTags(data.tags.map((tag) => tag.id));
      } catch (err) {
        setError(err instanceof Error ? err.message : "Failed to load entry");
      } finally {
        setIsLoading(false);
      }
    }
    void loadEntry();
  }, [slug]);

  // Load backlinks
  useEffect(() => {
    async function loadBacklinks(): Promise<void> {
      try {
        setBacklinksLoading(true);
        setBacklinksError(null);
        const data = await fetchBacklinks(slug);
        setBacklinks(data.backlinks);
      } catch (err) {
        setBacklinksError(err instanceof Error ? err.message : "Failed to load backlinks");
      } finally {
        setBacklinksLoading(false);
      }
    }
    void loadBacklinks();
  }, [slug]);

  // Load available tags
  useEffect(() => {
    async function loadTags(): Promise<void> {
      try {
        const tags = await fetchTags();
        setAvailableTags(tags);
      } catch (err) {
        console.error("Failed to load tags:", err);
      }
    }
    void loadTags();
  }, []);

  // Track unsaved changes
  useEffect(() => {
    if (!entry || !isEditing) {
      setHasUnsavedChanges(false);
      return;
    }

    const changed =
      editTitle !== entry.title ||
      editContent !== entry.content ||
      editStatus !== entry.status ||
      editVisibility !== entry.visibility ||
      JSON.stringify(editTags.sort()) !== JSON.stringify(entry.tags.map((t) => t.id).sort());

    setHasUnsavedChanges(changed);
  }, [entry, isEditing, editTitle, editContent, editStatus, editVisibility, editTags]);

  // Warn before leaving with unsaved changes
  useEffect(() => {
    const handleBeforeUnload = (e: BeforeUnloadEvent): string => {
      if (hasUnsavedChanges) {
        e.preventDefault();
        return "You have unsaved changes. Are you sure you want to leave?";
      }
      return "";
    };

    window.addEventListener("beforeunload", handleBeforeUnload);
    return (): void => {
      window.removeEventListener("beforeunload", handleBeforeUnload);
    };
  }, [hasUnsavedChanges]);

  // Save changes
  const handleSave = useCallback(async (): Promise<void> => {
    if (!entry || isSaving || !editTitle.trim() || !editContent.trim()) {
      return;
    }

    setIsSaving(true);
    setError(null);

    try {
      const updated = await updateEntry(slug, {
        title: editTitle.trim(),
        content: editContent.trim(),
        status: editStatus,
        visibility: editVisibility,
        tags: editTags,
      });

      setEntry(updated);
      setHasUnsavedChanges(false);
      setIsEditing(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to save changes");
    } finally {
      setIsSaving(false);
    }
  }, [entry, slug, editTitle, editContent, editStatus, editVisibility, editTags, isSaving]);

  // Cmd+S / Ctrl+S to save
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent): void => {
      if ((e.metaKey || e.ctrlKey) && e.key === "s" && isEditing) {
        e.preventDefault();
        void handleSave();
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    return (): void => {
      window.removeEventListener("keydown", handleKeyDown);
    };
  }, [handleSave, isEditing]);

  const handleEdit = (): void => {
    if (!entry) return;
    setIsEditing(true);
  };

  const handleCancel = (): void => {
    if (!entry) return;

    if (
      !hasUnsavedChanges ||
      confirm("You have unsaved changes. Are you sure you want to cancel?")
    ) {
      setEditTitle(entry.title);
      setEditContent(entry.content);
      setEditStatus(entry.status);
      setEditVisibility(entry.visibility);
      setEditTags(entry.tags.map((tag) => tag.id));
      setIsEditing(false);
      setHasUnsavedChanges(false);
    }
  };

  const handleDelete = async (): Promise<void> => {
    if (
      !confirm(
        "Are you sure you want to delete this entry? It will be archived and can be restored later."
      )
    ) {
      return;
    }

    try {
      await deleteEntry(slug);
      router.push("/knowledge");
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to delete entry");
    }
  };

  const handleVersionRestore = (): void => {
    // Reload entry after version restore
    async function reload(): Promise<void> {
      try {
        const data = await fetchEntry(slug);
        setEntry(data);
        setEditTitle(data.title);
        setEditContent(data.content);
        setEditStatus(data.status);
        setEditVisibility(data.visibility);
        setEditTags(data.tags.map((tag) => tag.id));
        setActiveTab("content");
      } catch (err) {
        setError(err instanceof Error ? err.message : "Failed to reload entry");
      }
    }
    void reload();
  };

  if (isLoading) {
    return (
      <div className="max-w-4xl mx-auto p-6">
        <div className="animate-pulse space-y-4">
          <div className="h-8 bg-gray-200 dark:bg-gray-700 rounded w-3/4"></div>
          <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/2"></div>
          <div className="h-64 bg-gray-200 dark:bg-gray-700 rounded"></div>
        </div>
      </div>
    );
  }

  if (error && !entry) {
    return (
      <div className="max-w-4xl mx-auto p-6">
        <div className="p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md">
          <p className="text-sm text-red-800 dark:text-red-200">{error}</p>
        </div>
      </div>
    );
  }

  if (!entry) {
    return (
      <div className="max-w-4xl mx-auto p-6">
        <div className="p-4 bg-gray-50 dark:bg-gray-900/20 border border-gray-200 dark:border-gray-800 rounded-md">
          <p className="text-sm text-gray-800 dark:text-gray-200">Entry not found</p>
        </div>
      </div>
    );
  }

  return (
    <div className="max-w-4xl mx-auto p-6">
      {/* Header */}
      <div className="mb-6">
        {isEditing ? (
          <div className="space-y-4">
            <EntryMetadata
              title={editTitle}
              status={editStatus}
              visibility={editVisibility}
              selectedTags={editTags}
              availableTags={availableTags}
              onTitleChange={setEditTitle}
              onStatusChange={setEditStatus}
              onVisibilityChange={setEditVisibility}
              onTagsChange={setEditTags}
            />
          </div>
        ) : (
          <>
            <h1 className="text-3xl font-bold text-gray-900 dark:text-gray-100">{entry.title}</h1>
            <div className="mt-3 flex items-center gap-4 flex-wrap">
              {/* Status Badge */}
              <span
                className={`px-3 py-1 rounded-full text-xs font-medium ${
                  entry.status === EntryStatus.PUBLISHED
                    ? "bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200"
                    : entry.status === EntryStatus.DRAFT
                      ? "bg-yellow-100 dark:bg-yellow-900 text-yellow-800 dark:text-yellow-200"
                      : "bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200"
                }`}
              >
                {entry.status}
              </span>

              {/* Visibility Badge */}
              <span className="px-3 py-1 rounded-full text-xs font-medium bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200">
                {entry.visibility}
              </span>

              {/* Tags */}
              {entry.tags.map((tag) => (
                <span
                  key={tag.id}
                  className="px-3 py-1 rounded-full text-xs font-medium bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300"
                  style={tag.color ? { backgroundColor: tag.color } : undefined}
                >
                  {tag.name}
                </span>
              ))}
            </div>
          </>
        )}
      </div>

      {error && (
        <div className="mb-6 p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md">
          <p className="text-sm text-red-800 dark:text-red-200">{error}</p>
        </div>
      )}

      {/* Tabs */}
      {!isEditing && (
        <div className="mb-6 border-b border-gray-200 dark:border-gray-700">
          <nav className="flex gap-6">
            <button
              type="button"
              onClick={() => {
                setActiveTab("content");
              }}
              className={`pb-3 border-b-2 font-medium text-sm transition-colors ${
                activeTab === "content"
                  ? "border-blue-600 text-blue-600 dark:text-blue-400"
                  : "border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300"
              }`}
            >
              Content
            </button>
            <button
              type="button"
              onClick={() => {
                setActiveTab("history");
              }}
              className={`pb-3 border-b-2 font-medium text-sm transition-colors ${
                activeTab === "history"
                  ? "border-blue-600 text-blue-600 dark:text-blue-400"
                  : "border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300"
              }`}
            >
              History
            </button>
          </nav>
        </div>
      )}

      {/* Content */}
      <div className="mb-6">
        {isEditing ? (
          <EntryEditor content={editContent} onChange={setEditContent} />
        ) : activeTab === "content" ? (
          <>
            <EntryViewer entry={entry} />

            {/* Backlinks Section */}
            <div className="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
              <BacklinksList
                backlinks={backlinks}
                isLoading={backlinksLoading}
                error={backlinksError}
              />
            </div>
          </>
        ) : (
          <VersionHistory slug={slug} onRestore={handleVersionRestore} />
        )}
      </div>

      {/* Actions */}
      <div className="flex justify-between items-center pt-4 border-t border-gray-200 dark:border-gray-700">
        <div>
          {isEditing && (
            <button
              type="button"
              onClick={handleDelete}
              disabled={isSaving}
              className="px-4 py-2 text-sm font-medium text-red-700 dark:text-red-400 hover:text-red-900 dark:hover:text-red-300 disabled:opacity-50"
            >
              Delete
            </button>
          )}
        </div>

        <div className="flex gap-3">
          {isEditing ? (
            <>
              <button
                type="button"
                onClick={handleCancel}
                disabled={isSaving}
                className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700 disabled:opacity-50"
              >
                Cancel
              </button>
              <button
                type="button"
                onClick={handleSave}
                disabled={isSaving || !editTitle.trim() || !editContent.trim()}
                className="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 disabled:opacity-50"
              >
                {isSaving ? "Saving..." : "Save Changes"}
              </button>
            </>
          ) : (
            <button
              type="button"
              onClick={handleEdit}
              className="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700"
            >
              Edit
            </button>
          )}
        </div>
      </div>

      {isEditing && (
        <p className="mt-4 text-xs text-gray-500 dark:text-gray-400 text-center">
          Press <kbd className="px-2 py-1 bg-gray-100 dark:bg-gray-800 rounded">Cmd+S</kbd> or{" "}
          <kbd className="px-2 py-1 bg-gray-100 dark:bg-gray-800 rounded">Ctrl+S</kbd> to save
        </p>
      )}
    </div>
  );
}
