"use client";

import type { ReactElement } from "react";

import { useState, useEffect, useCallback } from "react";
import type { KnowledgeEntryWithTags, KnowledgeTag } from "@mosaic/shared";
import type { EntryStatus } from "@mosaic/shared";
import { EntryList } from "@/components/knowledge/EntryList";
import { EntryFilters } from "@/components/knowledge/EntryFilters";
import { ImportExportActions } from "@/components/knowledge";
import { fetchEntries, fetchTags } from "@/lib/api/knowledge";
import type { EntriesResponse } from "@/lib/api/knowledge";
import { MosaicSpinner } from "@/components/ui/MosaicSpinner";
import Link from "next/link";
import { Plus } from "lucide-react";

export default function KnowledgePage(): ReactElement {
  // Data state
  const [entries, setEntries] = useState<KnowledgeEntryWithTags[]>([]);
  const [tags, setTags] = useState<KnowledgeTag[]>([]);
  const [totalEntries, setTotalEntries] = useState(0);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Filter and sort state
  const [selectedStatus, setSelectedStatus] = useState<EntryStatus | "all">("all");
  const [selectedTag, setSelectedTag] = useState<string>("all");
  const [searchQuery, setSearchQuery] = useState("");
  const [sortBy, setSortBy] = useState<"updatedAt" | "createdAt" | "title">("updatedAt");
  const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc");

  // Pagination state
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = 10;

  // Load tags on mount
  useEffect(() => {
    let cancelled = false;

    fetchTags()
      .then((result) => {
        if (!cancelled) {
          setTags(result);
        }
      })
      .catch((err: unknown) => {
        console.error("Failed to load tags:", err);
      });

    return (): void => {
      cancelled = true;
    };
  }, []);

  // Load entries when filters/sort/page change
  const loadEntries = useCallback(async (): Promise<void> => {
    setIsLoading(true);
    setError(null);

    try {
      const filters: Record<string, unknown> = {
        page: currentPage,
        limit: itemsPerPage,
        sortBy,
        sortOrder,
      };

      if (selectedStatus !== "all") {
        filters.status = selectedStatus;
      }
      if (selectedTag !== "all") {
        filters.tag = selectedTag;
      }
      if (searchQuery.trim()) {
        filters.search = searchQuery.trim();
      }

      const response: EntriesResponse = await fetchEntries(
        filters as Parameters<typeof fetchEntries>[0]
      );
      setEntries(response.data);
      setTotalEntries(response.meta?.total ?? response.data.length);
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : "Failed to load entries");
    } finally {
      setIsLoading(false);
    }
  }, [currentPage, itemsPerPage, sortBy, sortOrder, selectedStatus, selectedTag, searchQuery]);

  useEffect(() => {
    void loadEntries();
  }, [loadEntries]);

  const totalPages = Math.max(1, Math.ceil(totalEntries / itemsPerPage));

  // Reset to page 1 when filters change
  const handleFilterChange = (callback: () => void): void => {
    callback();
    setCurrentPage(1);
  };

  const handleSortChange = (
    newSortBy: "updatedAt" | "createdAt" | "title",
    newSortOrder: "asc" | "desc"
  ): void => {
    setSortBy(newSortBy);
    setSortOrder(newSortOrder);
    setCurrentPage(1);
  };

  if (isLoading && entries.length === 0) {
    return (
      <main className="container mx-auto px-4 py-8 max-w-5xl">
        <div className="flex justify-center items-center py-20">
          <MosaicSpinner size={48} label="Loading knowledge base..." />
        </div>
      </main>
    );
  }

  return (
    <main className="container mx-auto px-4 py-8 max-w-5xl">
      {/* Header */}
      <div className="mb-8">
        <div className="flex items-center justify-between mb-4">
          <div>
            <h1 className="text-3xl font-bold text-gray-900">Knowledge Base</h1>
            <p className="text-gray-600 mt-2">Documentation, guides, and knowledge entries</p>
          </div>

          {/* Create button */}
          <Link
            href="/knowledge/new"
            className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors shadow-sm"
          >
            <Plus className="w-5 h-5" />
            <span>Create Entry</span>
          </Link>
        </div>

        {/* Import/Export Actions */}
        <div className="flex justify-end">
          <ImportExportActions
            onImportComplete={() => {
              void loadEntries();
            }}
          />
        </div>
      </div>

      {/* Error state */}
      {error && (
        <div
          className="mb-6 p-4 rounded-lg border"
          style={{
            borderColor: "var(--danger)",
            background: "rgba(229,72,77,0.08)",
          }}
        >
          <p className="text-sm" style={{ color: "var(--danger)" }}>
            {error}
          </p>
          <button
            type="button"
            onClick={() => {
              void loadEntries();
            }}
            className="mt-2 text-sm font-medium underline"
            style={{ color: "var(--danger)" }}
          >
            Retry
          </button>
        </div>
      )}

      {/* Filters */}
      <EntryFilters
        selectedStatus={selectedStatus}
        selectedTag={selectedTag}
        searchQuery={searchQuery}
        sortBy={sortBy}
        sortOrder={sortOrder}
        tags={tags}
        onStatusChange={(status) => {
          handleFilterChange(() => {
            setSelectedStatus(status);
          });
        }}
        onTagChange={(tag) => {
          handleFilterChange(() => {
            setSelectedTag(tag);
          });
        }}
        onSearchChange={(query) => {
          handleFilterChange(() => {
            setSearchQuery(query);
          });
        }}
        onSortChange={handleSortChange}
      />

      {/* Entry list */}
      <EntryList
        entries={entries}
        isLoading={isLoading}
        currentPage={currentPage}
        totalPages={totalPages}
        onPageChange={setCurrentPage}
      />
    </main>
  );
}
