/**
 * Repositories Browser Page
 * 浏览特定 Registry 的所有 Repositories
 */
import React, { useState, useEffect } from "react";
import { Database, RefreshCw, ArrowLeft, Search, Package } from "lucide-react";
import { useNavigate, useParams } from "react-router-dom";
import { useToast } from "@/shared";
import { 
  PageHeader, 
  Button, 
  LoadingState, 
  ErrorState, 
  EmptyState 
} from "@/shared/components";
import { listRegistries, listRepositories } from "@/api";
import type { ListRepositories200Item, RepositoryListResponse } from "@/api";
import { RepositoryItem } from "../components/RepositoryItem";
import { globalCache } from "@/shared/services/artifact-cache";
import { RegistryErrors, SuccessMessages, formatApiError } from "@/shared/utils";

const RepositoriesBrowserPage: React.FC = () => {
  const { registryId } = useParams<{ registryId: string }>();
  const navigate = useNavigate();
  const { info: toastInfo, success: toastSuccess, error: toastError } = useToast();

  const [repositories, setRepositories] = useState<string[]>([]);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [searchTerm, setSearchTerm] = useState("");
  const [registryName, setRegistryName] = useState<string>("");
  const [registryUrl, setRegistryUrl] = useState<string>("");

  // Load registry info
  useEffect(() => {
    const loadRegistryInfo = async () => {
      if (!registryId) return;
      try {
        const registries = await listRegistries();
        const foundRegistry = registries.find(r => r.id === registryId);
        if (foundRegistry) {
          setRegistryName(foundRegistry.name || "");
          setRegistryUrl(foundRegistry.url || "");
        }
      } catch (err) {
        console.error("Failed to load registry info:", err);
      }
    };
    loadRegistryInfo();
  }, [registryId]);

  // Load repositories
  const loadRepositories = async (
    isMounted = { current: true },
    skipCache = false,
    isRefresh = false
  ) => {
    let succeeded = false;
    if (!registryId) {
      setError("Registry ID is missing");
      setLoading(false);
      return false;
    }

    if (!skipCache && registryId) {
      const cached = globalCache.get<string[]>("repositories", registryId);
      if (cached) {
        console.log(`[RepositoriesBrowserPage] Using cached repositories for ${registryId}`);
        setRepositories(cached);
        setLoading(false);
        return true;
      }
    }

    if (isRefresh) {
      setRefreshing(true);
    } else {
      setLoading(true);
    }
    setError(null);
    try {
      const response = await listRepositories({ registryId });
      const repos = normalizeRepositoryNames(response);
      if (isMounted.current) {
        setRepositories(repos);
        if (registryId) {
          globalCache.set("repositories", repos, registryId);
        }
        succeeded = true;
      }
    } catch (err) {
      if (isMounted.current) {
        const errorMsg = formatApiError(err) || RegistryErrors.LOAD_FAILED;
        setError(errorMsg);
        toastError(errorMsg);
        console.error(err);
      }
    } finally {
      if (isMounted.current) {
        if (isRefresh) {
          setRefreshing(false);
        } else {
          setLoading(false);
        }
      }
    }
    return succeeded;
  };

  useEffect(() => {
    const isMounted = { current: true };
    loadRepositories(isMounted);
    return () => {
      isMounted.current = false;
    };
  }, [registryId]);

  const handleRefresh = async () => {
    toastInfo("Refreshing repositories...", {
      title: "Repositories Refresh",
      durationMs: 1800,
      mergeKey: "repositories-refresh",
    });
    globalCache.clearAll();
    const refreshed = await loadRepositories({ current: true }, true, true);
    if (refreshed) {
      toastSuccess(SuccessMessages.DATA_REFRESHED);
    }
  };

  const handleBack = () => {
    navigate("/artifact/registries");
  };

  const handleRepositoryClick = (repositoryName: string) => {
    if (registryId) {
      const encodedName = encodeURIComponent(repositoryName);
      navigate(`/artifact/registries/${registryId}/repositories/${encodedName}`);
    }
  };

  // Filter repositories by search term
  const filteredRepositories = repositories.filter((repo) =>
    repo.toLowerCase().includes(searchTerm.toLowerCase())
  );

  return (
    <div className="p-6">
      {/* Header */}
      <PageHeader
        title={`Repositories - ${registryName || registryId || "Registry"}`}
        description={`Browse repositories in ${registryName || registryId || "this registry"}`}
        icon={Database}
        iconColor="text-purple-400"
        actions={
          <>
            <Button
              variant="secondary"
              icon={ArrowLeft}
              onClick={handleBack}
            >
              Back
            </Button>
            <Button
              variant="secondary"
              icon={RefreshCw}
              onClick={handleRefresh}
              loading={refreshing}
              spinIcon={true}
            >
              Refresh
            </Button>
          </>
        }
      />

      {/* Search Bar */}
      {!loading && !error && repositories.length > 0 && (
        <div className="mt-4">
          <div className="relative">
            <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" />
            <input
              type="text"
              placeholder="Search repositories..."
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              className="w-full pl-10 pr-4 py-2 bg-dark-lighter border border-dark-border rounded-lg
                text-white placeholder-gray-500 focus:outline-none focus:border-purple-500
                focus:ring-1 focus:ring-purple-500"
            />
          </div>
        </div>
      )}

      {/* Loading State */}
      {loading && <LoadingState message="Loading repositories..." />}

      {/* Error State */}
      {error && !loading && (
        <ErrorState message={error} onRetry={handleRefresh} />
      )}

      {/* Empty State */}
      {!loading && !error && filteredRepositories.length === 0 && (
        <EmptyState
          icon={Database}
          title={searchTerm ? "No Repositories Found" : "No Repositories"}
          description={
            searchTerm
              ? `No repositories match "${searchTerm}"`
              : "This registry doesn't contain any repositories yet"
          }
          action={
            !searchTerm
              ? {
                  label: "Back to Registries",
                  icon: ArrowLeft,
                  onClick: handleBack,
                }
              : undefined
          }
        />
      )}

      {/* Repositories List */}
      {!loading && !error && filteredRepositories.length > 0 && (
        <div className="mt-6 space-y-3">
          {filteredRepositories.map((repo) => (
            <div
              key={repo}
              onClick={() => handleRepositoryClick(repo)}
              className="cursor-pointer"
            >
              <RepositoryItem
                registryId={registryId || ""}
                registryName={registryName}
                registryUrl={registryUrl}
                repository={repo}
              />
            </div>
          ))}
        </div>
      )}

      {/* Stats */}
      {!loading && repositories.length > 0 && (
        <div className="mt-6 p-4 bg-dark-card border border-dark-border rounded-lg">
          <div className="flex items-center gap-4 text-sm text-gray-400">
            <div className="flex items-center gap-2">
              <Database className="w-4 h-4" />
              <span>Registry:</span>
              <span className="text-white font-medium">{registryName || registryId}</span>
            </div>
            <div className="flex items-center gap-2">
              <Package className="w-4 h-4" />
              <span>Repositories:</span>
              <span className="text-white font-medium">
                {filteredRepositories.length}
                {searchTerm && ` of ${repositories.length}`}
              </span>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default RepositoriesBrowserPage;

function normalizeRepositoryNames(
  payload: RepositoryListResponse | ListRepositories200Item[] | null | undefined
): string[] {
  if (!payload) {
    return [];
  }

  if (Array.isArray(payload)) {
    return payload
      .map((repo) => (typeof repo === "string" ? repo : repo.name || ""))
      .filter((name): name is string => Boolean(name));
  }

  if (Array.isArray(payload.repositories)) {
    return payload.repositories.filter((name): name is string => typeof name === "string" && Boolean(name));
  }

  return [];
}
