"use client";

import { useEffect, useState } from "react";
import { useParams } from "next/navigation";
import {
  Loader2, AlertCircle, ChevronDown, ChevronRight,
  Box, Container, CircleDot,
} from "lucide-react";
import { GiteaFileTree } from "@/components/project/gitea-file-tree";
import { GiteaFileViewer } from "@/components/project/gitea-file-viewer";
import { useAnatomy, type Anatomy } from "@/components/project/use-anatomy";

/**
 * Product tab — everything that makes up the thing being shipped.
 *
 * Left rail (top → bottom):
 *   1. Codebases — Gitea repos, each tile expands inline into a file
 *      tree; clicking a file previews it on the right.
 *   2. Images — Coolify services backed by an upstream Docker image
 *      (Twenty CRM, n8n…). Clicking shows image meta on the right.
 *
 * Dev containers do not appear here — they are the AI's workshop, not
 * part of the product surface.
 */

type Selection =
  | { type: "file"; codebaseId: string; path: string }
  | { type: "image"; uuid: string }
  | null;

export default function ProductTab() {
  const params = useParams();
  const projectId = params.projectId as string;
  const { anatomy, loading, error } = useAnatomy(projectId);

  const codebases = anatomy?.product.codebases ?? null;
  const images    = anatomy?.product.images ?? null;
  const reason    = anatomy?.codebasesReason;

  const [expanded, setExpanded] = useState<Set<string>>(new Set());
  const [selection, setSelection] = useState<Selection>(null);

  useEffect(() => {
    if (codebases && codebases[0]) {
      setExpanded(prev => (prev.size === 0 ? new Set([codebases[0].id]) : prev));
    }
  }, [codebases]);

  useEffect(() => {
    setSelection(null);
    setExpanded(new Set());
  }, [projectId]);

  const toggleCodebase = (id: string) => {
    setExpanded(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const showLoading = loading && !anatomy;

  return (
    <div style={pageWrap}>
      <div style={grid}>
        {/* ── Left rail ── */}
        <section style={leftCol}>
          {showLoading && (
            <Inline><Loader2 size={13} className="animate-spin" /> Loading…</Inline>
          )}
          {error && !showLoading && (
            <Inline><AlertCircle size={13} /> {error}</Inline>
          )}

          {anatomy && (
            <>
              {/* Codebases */}
              <RailGroup title="Codebases" count={codebases?.length ?? 0}>
                {codebases && codebases.length === 0 && (
                  <RailEmpty>
                    {reason === "no_repo"
                      ? <>No codebase yet. <span style={nudge}>Try: &quot;Start building my app&quot;</span></>
                      : <>Repo is empty — push a first commit. <span style={nudge}>Try: &quot;Scaffold a Next.js app&quot;</span></>}
                  </RailEmpty>
                )}
                {codebases?.map(cb => {
                  const isOpen = expanded.has(cb.id);
                  return (
                    <article key={cb.id} style={codebaseTile}>
                      <button
                        type="button"
                        onClick={() => toggleCodebase(cb.id)}
                        style={tileHeader}
                        aria-expanded={isOpen}
                      >
                        <span style={chevronCell}>
                          {isOpen
                            ? <ChevronDown size={13} style={{ color: INK.mid }} />
                            : <ChevronRight size={13} style={{ color: INK.mid }} />}
                        </span>
                        <Box size={13} style={{ color: INK.mid, flexShrink: 0 }} />
                        <div style={{ minWidth: 0, textAlign: "left" }}>
                          <div style={tileLabel}>{cb.label}</div>
                          {cb.hint && <div style={tileHint}>{cb.hint}</div>}
                        </div>
                      </button>
                      {isOpen && (
                        <div style={tileBody}>
                          <GiteaFileTree
                            projectId={projectId}
                            rootPath={cb.path}
                            selectedPath={
                              selection?.type === "file" && selection.codebaseId === cb.id
                                ? selection.path
                                : undefined
                            }
                            onSelectFile={(p) =>
                              setSelection({ type: "file", codebaseId: cb.id, path: p })
                            }
                          />
                        </div>
                      )}
                    </article>
                  );
                })}
              </RailGroup>

              {/* Images */}
              <RailGroup title="Images" count={images?.length ?? 0}>
                {images && images.length === 0 && (
                  <RailEmpty>
                    Self-hosted tools (Twenty CRM, n8n, Plausible…) you run appear here.
                    <span style={nudge}>Try: &quot;Install Twenty CRM for my project&quot;</span>
                  </RailEmpty>
                )}
                {images?.map(img => (
                  <button
                    key={img.uuid}
                    type="button"
                    onClick={() => setSelection({ type: "image", uuid: img.uuid })}
                    style={{
                      ...flatTile,
                      borderColor: selection?.type === "image" && selection.uuid === img.uuid ? INK.ink : INK.borderSoft,
                      boxShadow:   selection?.type === "image" && selection.uuid === img.uuid ? `0 0 0 1px ${INK.ink}` : "none",
                      background:  selection?.type === "image" && selection.uuid === img.uuid ? "#fffdf8" : INK.cardBg,
                    }}
                    aria-pressed={selection?.type === "image" && selection.uuid === img.uuid}
                  >
                    <Container size={13} style={{ color: INK.mid, flexShrink: 0 }} />
                    <div style={{ minWidth: 0, textAlign: "left", flex: 1 }}>
                      <div style={tileLabel}>{img.name}</div>
                      <div style={tileHint}>
                        {img.image}{img.version ? `:${img.version}` : ""}
                      </div>
                    </div>
                    {img.status && <CircleDot size={9} style={{ color: statusColor(img.status), flexShrink: 0 }} />}
                  </button>
                ))}
              </RailGroup>
            </>
          )}
        </section>

        {/* ── Right pane ── */}
        <aside style={rightCol}>
          <h3 style={heading}>{paneHeading(selection)}</h3>
          <div style={panel}>
            {selection?.type === "file" && (
              <GiteaFileViewer projectId={projectId} path={selection.path} />
            )}
            {selection?.type === "image" && anatomy && (
              <ImageDetail uuid={selection.uuid} anatomy={anatomy} />
            )}
            {!selection && (
              <Empty>Pick a codebase file or an image on the left.</Empty>
            )}
          </div>
        </aside>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────
// Image details (right pane)
// ──────────────────────────────────────────────────

function ImageDetail({ uuid, anatomy }: { uuid: string; anatomy: Anatomy }) {
  const img = anatomy.product.images.find(i => i.uuid === uuid);
  if (!img) return <Empty>This image is no longer in the project.</Empty>;
  const live = anatomy.hosting.live.find(l => l.uuid === uuid);

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 1 }}>
      <DetailRow label="Image"   value={img.image} />
      <DetailRow label="Version" value={img.version || "latest"} />
      <DetailRow label="Type"    value={img.serviceType ?? "—"} />
      <DetailRow
        label="Status"
        value={img.status ?? "unknown"}
        dot={statusColor(img.status ?? "")}
      />
      {live?.fqdn && (
        <DetailRow label="URL" value={live.fqdn} href={`https://${live.fqdn}`} />
      )}
    </div>
  );
}

// ──────────────────────────────────────────────────
// Bits
// ──────────────────────────────────────────────────

function RailGroup({
  title, count, children,
}: { title: string; count: number; children: React.ReactNode }) {
  return (
    <div style={railGroup}>
      <header style={railGroupHeader}>
        <span style={railGroupTitle}>{title}</span>
        <span style={countPill}>{count}</span>
      </header>
      <div style={railItems}>{children}</div>
    </div>
  );
}

function RailEmpty({ children }: { children: React.ReactNode }) {
  return <div style={railEmpty}>{children}</div>;
}

function DetailRow({
  label, value, dot, href,
}: { label: string; value: string; dot?: string; href?: string }) {
  return (
    <div style={detailRow}>
      <span style={detailLabel}>{label}</span>
      <span style={detailValue}>
        {dot && <CircleDot size={9} style={{ color: dot, marginRight: 6 }} />}
        {href ? (
          <a href={href} target="_blank" rel="noreferrer" style={detailLink}>{value}</a>
        ) : value}
      </span>
    </div>
  );
}

function Inline({ children }: { children: React.ReactNode }) {
  return (
    <div style={{
      display: "flex", alignItems: "center", gap: 8,
      padding: "12px 14px", fontSize: "0.82rem", color: INK.mid,
      background: INK.cardBg, border: `1px solid ${INK.borderSoft}`, borderRadius: 8,
    }}>
      {children}
    </div>
  );
}

function Empty({ children }: { children: React.ReactNode }) {
  return (
    <div style={{
      flex: 1, display: "flex", alignItems: "center", justifyContent: "center",
      color: INK.mid, fontSize: "0.85rem", padding: "32px 16px", textAlign: "center",
    }}>
      {children}
    </div>
  );
}

// ──────────────────────────────────────────────────

function paneHeading(s: Selection): string {
  if (!s) return "Preview";
  if (s.type === "file") return `Preview · ${shortPath(s.path)}`;
  return "Image";
}
function shortPath(p: string) {
  const parts = p.split("/");
  if (parts.length <= 2) return p;
  return ".../" + parts.slice(-2).join("/");
}
function statusColor(status: string) {
  const s = status.toLowerCase();
  if (s.includes("running") || s.includes("healthy")) return "#2e7d32";
  if (s.includes("starting") || s.includes("deploying")) return "#d4a04a";
  if (s.includes("exit") || s.includes("fail") || s.includes("unhealthy")) return "#c5392b";
  return "#a09a90";
}

// ──────────────────────────────────────────────────
// Tokens
// ──────────────────────────────────────────────────

const INK = {
  ink: "#1a1a1a",
  mid: "#5f5e5a",
  muted: "#a09a90",
  border: "#e8e4dc",
  borderSoft: "#efebe1",
  cardBg: "#fff",
  fontSans: '"Outfit", "Inter", ui-sans-serif, sans-serif',
} as const;

const pageWrap: React.CSSProperties = {
  padding: "28px 48px 48px",
  fontFamily: INK.fontSans,
  color: INK.ink,
};
const grid: React.CSSProperties = {
  display: "grid",
  gridTemplateColumns: "minmax(280px, 360px) minmax(0, 1fr)",
  gap: 28,
  maxWidth: 1400,
  margin: "0 auto",
  alignItems: "stretch",
};
const leftCol: React.CSSProperties = {
  minWidth: 0, display: "flex", flexDirection: "column", gap: 18,
};
const rightCol: React.CSSProperties = {
  minWidth: 0, display: "flex", flexDirection: "column",
};
const heading: React.CSSProperties = {
  fontSize: "0.72rem", fontWeight: 600, letterSpacing: "0.12em",
  textTransform: "uppercase", color: INK.muted, margin: "0 0 14px",
};
const railGroup: React.CSSProperties = { display: "flex", flexDirection: "column" };
const railGroupHeader: React.CSSProperties = {
  display: "flex", alignItems: "center", justifyContent: "space-between",
  padding: "0 4px 8px",
};
const railGroupTitle: React.CSSProperties = {
  fontSize: "0.68rem", fontWeight: 600, letterSpacing: "0.12em",
  textTransform: "uppercase", color: INK.muted,
};
const countPill: React.CSSProperties = {
  fontSize: "0.7rem", fontWeight: 600, color: INK.mid,
  padding: "1px 7px", borderRadius: 999, background: "#f3eee4",
};
const railItems: React.CSSProperties = { display: "flex", flexDirection: "column", gap: 10 };
const railEmpty: React.CSSProperties = {
  padding: "10px 12px", fontSize: "0.74rem", color: INK.muted,
  border: `1px dashed ${INK.borderSoft}`, borderRadius: 8,
  lineHeight: 1.6,
};
const nudge: React.CSSProperties = {
  display: "block", marginTop: 6, fontStyle: "normal",
  background: "#f3eee4", borderRadius: 4, padding: "3px 8px",
  fontSize: "0.72rem", color: "#7a6a50",
};
const flatTile: React.CSSProperties = {
  display: "flex", alignItems: "center", gap: 10,
  width: "100%", padding: "12px 14px",
  background: INK.cardBg, border: `1px solid ${INK.borderSoft}`, borderRadius: 10,
  cursor: "pointer", font: "inherit", color: "inherit",
  transition: "border-color 0.12s, background 0.12s, box-shadow 0.12s",
};
const codebaseTile: React.CSSProperties = {
  background: INK.cardBg, border: `1px solid ${INK.borderSoft}`, borderRadius: 10, overflow: "hidden",
};
const tileHeader: React.CSSProperties = {
  display: "flex", alignItems: "center", gap: 8, width: "100%",
  padding: "12px 14px", background: "transparent", border: "none",
  cursor: "pointer", font: "inherit", color: "inherit",
};
const tileLabel: React.CSSProperties = {
  fontSize: "0.85rem", fontWeight: 600, color: INK.ink, marginBottom: 2,
};
const tileHint: React.CSSProperties = { fontSize: "0.74rem", color: INK.mid, lineHeight: 1.4 };
const tileBody: React.CSSProperties = {
  padding: "8px 10px 12px", borderTop: `1px solid ${INK.borderSoft}`,
};
const chevronCell: React.CSSProperties = {
  width: 14, display: "inline-flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
};
const panel: React.CSSProperties = {
  background: INK.cardBg, border: `1px solid ${INK.border}`, borderRadius: 10,
  padding: 16, flex: 1, minHeight: 0, display: "flex", flexDirection: "column",
};
const detailRow: React.CSSProperties = {
  display: "flex", alignItems: "center", justifyContent: "space-between",
  padding: "12px 4px", borderBottom: `1px solid ${INK.borderSoft}`,
};
const detailLabel: React.CSSProperties = {
  fontSize: "0.72rem", fontWeight: 600, letterSpacing: "0.06em",
  textTransform: "uppercase", color: INK.muted,
};
const detailValue: React.CSSProperties = {
  fontSize: "0.85rem", color: INK.ink, display: "inline-flex", alignItems: "center",
};
const detailLink: React.CSSProperties = {
  color: INK.ink, textDecoration: "underline",
};
