"use client";

import { useState, useCallback, useEffect } from "react";
import {
  StemeDBClient,
  type GetPatternsResponse,
  ApiError,
} from "@/lib/api";
import type { PanelState } from "@/lib/types";
import { CORPUS_FETCH_LIMIT, DEFAULT_MIN_PROJECTS } from "./constants";
import { ErrorState } from "@/components/shared/error-state";
import { CorpusFilters } from "./corpus-filters";
import { CorpusList } from "./corpus-list";
import { CorpusLoadingSkeleton } from "./corpus-loading-skeleton";
import { CorpusEmptyState } from "./corpus-empty-state";

export function CorpusPanel() {
  const [state, setState] = useState<PanelState<GetPatternsResponse>>({
    status: "idle",
  });

  // Input state (controlled form inputs) - doesn't trigger fetch
  const [inputPrefix, setInputPrefix] = useState("");
  const [inputMinProjects, setInputMinProjects] = useState(DEFAULT_MIN_PROJECTS);

  // Search state (actual search params) - triggers fetch
  const [searchPrefix, setSearchPrefix] = useState("");
  const [searchMinProjects, setSearchMinProjects] = useState(DEFAULT_MIN_PROJECTS);

  const fetchData = useCallback(async () => {
    setState({ status: "loading" });
    try {
      const client = new StemeDBClient();
      const data = await client.getPatterns({
        subjectPrefix: searchPrefix || undefined,
        minProjects: searchMinProjects,
        limit: CORPUS_FETCH_LIMIT,
      });
      setState({ status: "success", data });
    } catch (err) {
      // 404 means no patterns - treat as empty success
      if (err instanceof ApiError && err.status === 404) {
        setState({
          status: "success",
          data: { patterns: [], total_matching: 0 },
        });
        return;
      }
      const message =
        err instanceof ApiError
          ? err.userMessage
          : err instanceof Error
            ? err.message
            : "Unknown error";
      setState({ status: "error", error: message });
    }
  }, [searchPrefix, searchMinProjects]);

  // Fetch on mount
  useEffect(() => {
    fetchData();
  }, [fetchData]);

  // Handle form submit - update search params which triggers fetch
  const handleSubmit = useCallback(() => {
    setSearchPrefix(inputPrefix);
    setSearchMinProjects(inputMinProjects);
  }, [inputPrefix, inputMinProjects]);

  // Handle clear - reset both input and search state
  const handleClear = useCallback(() => {
    setInputPrefix("");
    setInputMinProjects(DEFAULT_MIN_PROJECTS);
    setSearchPrefix("");
    setSearchMinProjects(DEFAULT_MIN_PROJECTS);
  }, []);

  // Patterns from successful state (filtering done server-side)
  const patterns = state.status === "success" ? state.data.patterns : [];

  const hasActiveFilter = searchPrefix !== "" || searchMinProjects > DEFAULT_MIN_PROJECTS;

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="rounded-lg border border-border bg-card p-6">
        <h2 className="text-lg font-medium text-card-foreground mb-2">
          Community Corpus
        </h2>
        <p className="text-sm text-muted-foreground">
          Explore patterns discovered across projects using Aphoria. These anonymized
          observations help establish community consensus on configurations and practices.
        </p>
      </div>

      {/* Content */}
      <div className="rounded-lg border border-border bg-card p-6">
        <div className="space-y-6">
          {/* Filters - always visible */}
          <CorpusFilters
            subjectPrefix={inputPrefix}
            minProjects={inputMinProjects}
            onSubjectPrefixChange={setInputPrefix}
            onMinProjectsChange={setInputMinProjects}
            onSubmit={handleSubmit}
            onClear={handleClear}
            totalCount={state.status === "success" ? state.data.total_matching : 0}
            filteredCount={patterns.length}
            isLoading={state.status === "loading"}
            hasActiveFilter={hasActiveFilter}
          />

          {/* Loading State */}
          {state.status === "loading" && <CorpusLoadingSkeleton />}

          {/* Error State */}
          {state.status === "error" && (
            <ErrorState
              title="Failed to Load Patterns"
              error={state.error}
              onRetry={fetchData}
            />
          )}

          {/* Success State */}
          {state.status === "success" && (
            <>
              {patterns.length === 0 ? (
                <CorpusEmptyState
                  hasFilter={hasActiveFilter}
                  onClearFilter={handleClear}
                />
              ) : (
                <CorpusList patterns={patterns} />
              )}
            </>
          )}

          {/* Initial/Idle State */}
          {state.status === "idle" && <CorpusLoadingSkeleton />}
        </div>
      </div>
    </div>
  );
}
