"use client";

import { useEffect, useState, useCallback } from "react";
import { getAvailableApps, installIntegration, AvailableApp } from "@/lib/api";
import { Search, Star, Download, RefreshCw, Puzzle } from "lucide-react";

interface AppDirectoryProps {
  onInstalled?: () => void;
}

export function AppDirectory({ onInstalled }: AppDirectoryProps) {
  const [apps, setApps] = useState<AvailableApp[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");
  const [search, setSearch] = useState("");
  const [installing, setInstalling] = useState<string | null>(null);
  const [installedIds, setInstalledIds] = useState<Set<string>>(new Set());

  const loadApps = useCallback(() => {
    setLoading(true);
    setError("");
    getAvailableApps()
      .then((data) => setApps(Array.isArray(data) ? data : []))
      .catch((err) => {
        console.error("Failed to load app directory:", err);
        setError("Failed to load app directory");
      })
      .finally(() => setLoading(false));
  }, []);

  useEffect(() => {
    loadApps();
  }, [loadApps]);

  const handleInstall = (app: AvailableApp) => {
    setInstalling(app.id);
    installIntegration(app.id)
      .then(() => {
        setInstalledIds((prev) => new Set(prev).add(app.id));
        onInstalled?.();
      })
      .catch((err) => console.error("Failed to install:", err))
      .finally(() => setInstalling(null));
  };

  const filtered = apps.filter((app) =>
    app.name.toLowerCase().includes(search.toLowerCase()) ||
    (app.description || "").toLowerCase().includes(search.toLowerCase()) ||
    (app.category || "").toLowerCase().includes(search.toLowerCase())
  );

  if (loading) {
    return (
      <div className="flex items-center justify-center text-gray-400 py-12">
        <RefreshCw size={20} className="animate-pulse" />
      </div>
    );
  }

  if (error) {
    return (
      <div className="flex items-center justify-center text-slack-red py-12 text-sm">
        {error}
        <button
          onClick={loadApps}
          className="ml-2 text-slack-purple hover:underline"
        >
          Retry
        </button>
      </div>
    );
  }

  return (
    <div>
      {/* Search bar */}
      <div className="relative mb-4">
        <Search size={16} className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" />
        <input
          type="text"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          placeholder="Search apps..."
          className="w-full pl-9 pr-3 py-2 rounded-md border border-gray-300 text-sm focus:outline-none focus:ring-2 focus:ring-slack-purple"
        />
      </div>

      {filtered.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-16 text-gray-400">
          <Puzzle size={48} className="mb-3 opacity-50" />
          <p className="text-sm">
            {search ? "No apps found." : "No apps available."}
          </p>
        </div>
      ) : (
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
          {filtered.map((app) => {
            const isInstalled = installedIds.has(app.id);
            return (
              <div
                key={app.id}
                className="p-4 rounded-lg border border-gray-200 bg-white shadow-sm hover:border-slack-purple/30 transition-colors"
              >
                <div className="flex items-start gap-3">
                  <div className="w-10 h-10 rounded-lg bg-gray-100 flex items-center justify-center flex-shrink-0">
                    {app.icon_url ? (
                      // eslint-disable-next-line @next/next/no-img-element
                      <img
                        src={app.icon_url}
                        alt={app.name}
                        className="w-8 h-8 rounded-md object-contain"
                      />
                    ) : (
                      <span className="text-lg font-bold text-slack-purple">
                        {app.name[0]?.toUpperCase() || "A"}
                      </span>
                    )}
                  </div>
                  <div className="flex-1 min-w-0">
                    <h3 className="font-semibold text-gray-800 truncate">
                      {app.name}
                    </h3>
                    {app.developer && (
                      <p className="text-xs text-gray-400">{app.developer}</p>
                    )}
                    {app.description && (
                      <p className="text-sm text-gray-500 mt-1 line-clamp-2">
                        {app.description}
                      </p>
                    )}
                    <div className="flex items-center gap-3 mt-2 text-xs text-gray-400">
                      {app.category && (
                        <span className="px-2 py-0.5 rounded bg-gray-100">
                          {app.category}
                        </span>
                      )}
                      {app.rating !== undefined && (
                        <span className="flex items-center gap-0.5">
                          <Star size={10} className="fill-slack-yellow text-slack-yellow" />
                          {app.rating.toFixed(1)}
                        </span>
                      )}
                      {app.install_count !== undefined && (
                        <span>{app.install_count.toLocaleString()} installs</span>
                      )}
                    </div>
                    <button
                      onClick={() => handleInstall(app)}
                      disabled={installing === app.id || isInstalled}
                      className={`mt-3 flex items-center gap-1 px-3 py-1.5 rounded-md text-xs font-medium transition-colors disabled:opacity-50 ${
                        isInstalled
                          ? 'bg-slack-green/10 text-slack-green'
                          : 'bg-slack-purple text-white hover:bg-slack-darkpurple'
                      }`}
                    >
                      <Download size={12} />
                      {installing === app.id
                        ? "Installing..."
                        : isInstalled
                        ? "Installed"
                        : "Install"}
                    </button>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

export default AppDirectory;