import { useState } from "react";
import {
  downloadAndInstallApp,
  launchApp,
  uninstallApp,
} from "../lib/commands";
import type { AppEntry, InstalledApp } from "../types/manifest";
import "./AppCard.css";

interface Props {
  app: AppEntry;
  installed?: InstalledApp;
  onRefresh: () => void;
}

type ActionState = "idle" | "downloading" | "launching" | "error";

export function AppCard({ app, installed, onRefresh }: Props) {
  const [state, setState] = useState<ActionState>("idle");
  const [errMsg, setErrMsg] = useState<string | null>(null);

  const isInstalled = !!installed;
  const hasUpdate = isInstalled && installed.version !== app.current_version;
  const initial = app.name.charAt(0).toUpperCase();

  async function handleInstallOrUpdate() {
    setState("downloading");
    setErrMsg(null);
    try {
      await downloadAndInstallApp(app);
      onRefresh();
    } catch (e: unknown) {
      const msg =
        e && typeof e === "object" && "message" in e
          ? String((e as { message: unknown }).message)
          : String(e);
      setErrMsg(msg);
      setState("error");
      return;
    }
    setState("idle");
  }

  async function handleLaunch() {
    setState("launching");
    setErrMsg(null);
    try {
      await launchApp(app.id);
    } catch (e: unknown) {
      const msg =
        e && typeof e === "object" && "message" in e
          ? String((e as { message: unknown }).message)
          : String(e);
      setErrMsg(msg);
      setState("error");
      return;
    }
    setState("idle");
  }

  async function handleUninstall() {
    if (!confirm(`Remove ${app.name} from the launcher? (Files are kept.)`)) return;
    try {
      await uninstallApp(app.id);
      onRefresh();
    } catch (e: unknown) {
      console.error(e);
    }
  }

  const busy = state === "downloading" || state === "launching";

  return (
    <article className={`app-card${hasUpdate ? " app-card--has-update" : ""}`}>
      {hasUpdate && (
        <span className="app-card__update-badge" title={`Update: v${app.current_version}`}>
          ↑
        </span>
      )}

      <div className="app-card__icon">
        {app.icon_url ? (
          <img src={app.icon_url} alt={app.name} />
        ) : (
          <span className="app-card__icon-fallback">{initial}</span>
        )}
      </div>

      <div className="app-card__info">
        <h3 className="app-card__name">{app.name}</h3>
        <p className="app-card__desc">{app.description}</p>
        <div className="app-card__meta">
          <span className="app-card__version">
            {isInstalled ? (
              <>
                <span className="app-card__installed-ver">{installed.version}</span>
                {hasUpdate && (
                  <span className="app-card__available-ver"> → {app.current_version}</span>
                )}
              </>
            ) : (
              `v${app.current_version}`
            )}
          </span>
          <span className="app-card__category">{app.category}</span>
        </div>
      </div>

      {state === "error" && errMsg && (
        <p className="app-card__error" title={errMsg}>
          {errMsg}
        </p>
      )}

      <div className="app-card__actions">
        {isInstalled && (
          <button
            className="app-card__btn app-card__btn--primary"
            onClick={handleLaunch}
            disabled={busy}
          >
            {state === "launching" ? "Launching…" : "Launch"}
          </button>
        )}

        {(!isInstalled || hasUpdate) && (
          <button
            className={`app-card__btn${isInstalled ? " app-card__btn--secondary" : " app-card__btn--primary"}`}
            onClick={handleInstallOrUpdate}
            disabled={busy}
          >
            {state === "downloading"
              ? "Downloading…"
              : hasUpdate
              ? `Update → v${app.current_version}`
              : "Install"}
          </button>
        )}

        {isInstalled && (
          <button
            className="app-card__btn app-card__btn--ghost"
            onClick={handleUninstall}
            disabled={busy}
            title="Remove from launcher"
          >
            ✕
          </button>
        )}
      </div>
    </article>
  );
}
