"use client";

/**
 * Project home page.
 *
 * Sits between the projects list and the AI interview. Gives users two
 * simplified entry tiles — Code (their Gitea repo) and Infrastructure
 * (their Coolify deployment) — plus a quiet "Continue setup" link if
 * the discovery interview isn't done.
 *
 * Styled to match the production "ink & parchment" design:
 * Newsreader serif headings, Outfit sans body, warm beige borders,
 * solid black CTAs. No indigo. No gradients.
 */

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useParams } from "next/navigation";
import { useSession } from "next-auth/react";
import { isClientDevProjectBypass } from "@/lib/dev-bypass";
import {
  ArrowRight,
  Code2,
  ExternalLink,
  FileText,
  Folder,
  Loader2,
  Rocket,
} from "lucide-react";

// ── Design tokens (mirrors the prod ink & parchment palette) ─────────
const INK = {
  fontSerif: '"Newsreader", "Lora", Georgia, serif',
  fontSans: '"Outfit", "Inter", ui-sans-serif, sans-serif',
  fontMono: '"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace',
  ink: "#1a1a1a",
  ink2: "#2c2c2a",
  mid: "#5f5e5a",
  muted: "#a09a90",
  stone: "#b5b0a6",
  border: "#e8e4dc",
  borderHover: "#d0ccc4",
  cardBg: "#fff",
  pageBg: "#f7f4ee",
  shadow: "0 1px 2px #1a1a1a05",
  shadowHover: "0 2px 8px #1a1a1a0a",
  iconWrapBg: "#1a1a1a08",
} as const;

interface ProjectSummary {
  id: string;
  productName?: string;
  name?: string;
  productVision?: string;
  description?: string;
  giteaRepo?: string;
  giteaRepoUrl?: string;
  stage?: "discovery" | "architecture" | "building" | "active";
  creationMode?: "fresh" | "chat-import" | "code-import" | "migration";
  discoveryPhase?: number;
  progress?: number;
}

interface FileTreeItem {
  name: string;
  path: string;
  type: "file" | "dir";
}

interface PreviewApp {
  name: string;
  url: string | null;
  status: string;
}

export default function ProjectHomePage() {
  const params = useParams();
  const workspace = params.workspace as string;
  const projectId = params.projectId as string;
  const { status: authStatus } = useSession();

  const [project, setProject] = useState<ProjectSummary | null>(null);
  const [projectLoading, setProjectLoading] = useState(true);

  const [files, setFiles] = useState<FileTreeItem[] | null>(null);
  const [filesLoading, setFilesLoading] = useState(true);

  const [apps, setApps] = useState<PreviewApp[]>([]);
  const [appsLoading, setAppsLoading] = useState(true);

  const ready = useMemo(
    () => isClientDevProjectBypass() || authStatus === "authenticated",
    [authStatus]
  );

  useEffect(() => {
    if (!ready) {
      if (authStatus === "unauthenticated") setProjectLoading(false);
      return;
    }
    fetch(`/api/projects/${projectId}`, { credentials: "include" })
      .then(r => r.json())
      .then(d => setProject(d.project ?? null))
      .catch(() => {})
      .finally(() => setProjectLoading(false));
  }, [ready, authStatus, projectId]);

  useEffect(() => {
    if (!ready) return;
    fetch(`/api/projects/${projectId}/file?path=`, { credentials: "include" })
      .then(r => (r.ok ? r.json() : null))
      .then(d => {
        if (d?.type === "dir" && Array.isArray(d.items)) {
          setFiles(d.items as FileTreeItem[]);
        } else {
          setFiles([]);
        }
      })
      .catch(() => setFiles([]))
      .finally(() => setFilesLoading(false));
  }, [ready, projectId]);

  useEffect(() => {
    if (!ready) return;
    fetch(`/api/projects/${projectId}/preview-url`, { credentials: "include" })
      .then(r => (r.ok ? r.json() : null))
      .then(d => setApps(Array.isArray(d?.apps) ? d.apps : []))
      .catch(() => {})
      .finally(() => setAppsLoading(false));
  }, [ready, projectId]);

  const projectName = project?.productName || project?.name || "Untitled project";
  const projectDesc = project?.productVision || project?.description;
  const stage = project?.stage ?? "discovery";
  const interviewIncomplete = stage === "discovery";
  const liveApp = apps.find(a => a.url) ?? apps[0] ?? null;

  if (projectLoading) {
    return (
      <div style={pageWrap}>
        <div style={centeredFiller}>
          <Loader2 className="animate-spin" size={22} style={{ color: INK.stone }} />
        </div>
      </div>
    );
  }

  if (!project) {
    return (
      <div style={pageWrap}>
        <div style={{ ...centeredFiller, color: INK.muted, fontSize: 14, fontFamily: INK.fontSans }}>
          Project not found.
        </div>
      </div>
    );
  }

  return (
    <div style={pageWrap}>
      <div style={pageInner}>
        {/* ── Hero ─────────────────────────────────────────────── */}
        <header style={heroStyle}>
          <div style={{ minWidth: 0, flex: 1 }}>
            <div style={eyebrow}>Project</div>
            <h1 style={heroTitle}>{projectName}</h1>
            {projectDesc && <p style={heroDesc}>{projectDesc}</p>}
          </div>
          <StagePill stage={stage} />
        </header>

        {/* ── Continue setup link (quiet, only when in discovery) ── */}
        {interviewIncomplete && (
          <Link
            href={`/${workspace}/project/${projectId}/overview`}
            style={continueRow}
          >
            <div style={{ display: "flex", alignItems: "center", gap: 12, minWidth: 0 }}>
              <span style={continueDot} />
              <div style={{ minWidth: 0 }}>
                <div style={continueTitle}>Continue setup</div>
                <div style={continueSub}>
                  Pick up the AI interview where you left off.
                </div>
              </div>
            </div>
            <ArrowRight size={16} style={{ color: INK.ink, flexShrink: 0 }} />
          </Link>
        )}

        {/* ── Two big tiles ────────────────────────────────────── */}
        <div style={tileGrid}>
          <CodeTile
            workspace={workspace}
            projectId={projectId}
            files={files}
            loading={filesLoading}
            giteaRepo={project.giteaRepo}
          />
          <InfraTile
            workspace={workspace}
            projectId={projectId}
            app={liveApp}
            loading={appsLoading}
          />
        </div>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────
// Tiles
// ──────────────────────────────────────────────────────────────────────

function CodeTile({
  workspace,
  projectId,
  files,
  loading,
  giteaRepo,
}: {
  workspace: string;
  projectId: string;
  files: FileTreeItem[] | null;
  loading: boolean;
  giteaRepo?: string;
}) {
  const items = files ?? [];
  const dirCount = items.filter(i => i.type === "dir").length;
  const fileCount = items.filter(i => i.type === "file").length;
  const previewItems = items.slice(0, 6);

  return (
    <Link href={`/${workspace}/project/${projectId}/code`} style={tileLink}>
      <article
        style={tileCard}
        onMouseEnter={hoverEnter}
        onMouseLeave={hoverLeave}
      >
        <header style={tileHeader}>
          <span style={tileIconWrap}>
            <Code2 size={16} />
          </span>
          <div style={{ flex: 1 }}>
            <h2 style={tileTitle}>Code</h2>
            <p style={tileSubtitle}>What the AI is building, file by file.</p>
          </div>
          <ArrowRight size={14} style={{ color: INK.muted }} />
        </header>

        <div style={tileBody}>
          {loading ? (
            <TileLoader label="Reading repository…" />
          ) : items.length === 0 ? (
            <TileEmpty
              icon={<Folder size={18} />}
              title="No files yet"
              subtitle={
                giteaRepo
                  ? "Your repository is empty. The AI will commit the first files when you start building."
                  : "This project doesn't have a repository yet."
              }
            />
          ) : (
            <>
              <div style={tileMetaRow}>
                <Metric label="Folders" value={dirCount} />
                <Metric label="Files" value={fileCount} />
              </div>
              <ul style={fileList}>
                {previewItems.map(item => (
                  <li key={item.path} style={fileRow}>
                    <span style={fileIconWrap}>
                      {item.type === "dir" ? (
                        <Folder size={13} />
                      ) : (
                        <FileText size={13} />
                      )}
                    </span>
                    <span style={fileName}>{item.name}</span>
                    <span style={fileType}>
                      {item.type === "dir" ? "folder" : ext(item.name)}
                    </span>
                  </li>
                ))}
              </ul>
              {items.length > previewItems.length && (
                <div style={tileMore}>
                  +{items.length - previewItems.length} more
                </div>
              )}
            </>
          )}
        </div>
      </article>
    </Link>
  );
}

function InfraTile({
  workspace,
  projectId,
  app,
  loading,
}: {
  workspace: string;
  projectId: string;
  app: PreviewApp | null;
  loading: boolean;
}) {
  const status = app?.status?.toLowerCase() ?? "unknown";
  const isLive = !!app?.url && (status.includes("running") || status.includes("healthy"));
  const isBuilding = status.includes("queued") || status.includes("in_progress") || status.includes("starting");

  return (
    <Link href={`/${workspace}/project/${projectId}/infrastructure`} style={tileLink}>
      <article
        style={tileCard}
        onMouseEnter={hoverEnter}
        onMouseLeave={hoverLeave}
      >
        <header style={tileHeader}>
          <span style={tileIconWrap}>
            <Rocket size={16} />
          </span>
          <div style={{ flex: 1 }}>
            <h2 style={tileTitle}>Infrastructure</h2>
            <p style={tileSubtitle}>What's live and how it's running.</p>
          </div>
          <ArrowRight size={14} style={{ color: INK.muted }} />
        </header>

        <div style={tileBody}>
          {loading ? (
            <TileLoader label="Checking deployment…" />
          ) : !app ? (
            <TileEmpty
              icon={<Rocket size={18} />}
              title="Nothing is live yet"
              subtitle="The AI will deploy your project here once the build is ready."
            />
          ) : (
            <>
              <div style={tileMetaRow}>
                <StatusBlock
                  color={isLive ? "#2e7d32" : isBuilding ? "#3d5afe" : "#9a7b3a"}
                  label={isLive ? "Live" : isBuilding ? "Building" : statusFriendly(status)}
                />
                <Metric label="App" value={app.name} />
              </div>
              {app.url ? (
                <div style={liveUrlRow}>
                  <span style={liveUrlLabel}>Live URL</span>
                  <span style={liveUrlValue}>{shortUrl(app.url)}</span>
                  <a
                    href={app.url}
                    target="_blank"
                    rel="noopener noreferrer"
                    onClick={e => e.stopPropagation()}
                    style={liveUrlOpen}
                    aria-label="Open live site"
                  >
                    <ExternalLink size={12} />
                  </a>
                </div>
              ) : (
                <div style={liveUrlRow}>
                  <span style={liveUrlLabel}>Status</span>
                  <span style={liveUrlValue}>{statusFriendly(status)}</span>
                </div>
              )}
            </>
          )}
        </div>
      </article>
    </Link>
  );
}

// ──────────────────────────────────────────────────────────────────────
// Small bits
// ──────────────────────────────────────────────────────────────────────

function StagePill({ stage }: { stage: string }) {
  const map: Record<string, { label: string; color: string; bg: string }> = {
    discovery:    { label: "Defining", color: "#9a7b3a", bg: "#d4a04a12" },
    architecture: { label: "Planning", color: "#3d5afe", bg: "#3d5afe10" },
    building:     { label: "Building", color: "#3d5afe", bg: "#3d5afe10" },
    active:       { label: "Live",     color: "#2e7d32", bg: "#2e7d3210" },
  };
  const s = map[stage] ?? map.discovery;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 6,
      padding: "3px 9px", borderRadius: 4,
      fontSize: "0.68rem", fontWeight: 600, letterSpacing: "0.02em",
      color: s.color, background: s.bg, fontFamily: INK.fontSans,
      whiteSpace: "nowrap", flexShrink: 0,
    }}>
      <span style={{ width: 7, height: 7, borderRadius: "50%", background: s.color }} />
      {s.label}
    </span>
  );
}

function StatusBlock({ color, label }: { color: string; label: string }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
      <span style={metricLabel}>Status</span>
      <span style={{
        display: "inline-flex", alignItems: "center", gap: 6,
        fontSize: 13, color: INK.ink, fontFamily: INK.fontSans, fontWeight: 500,
      }}>
        <span style={{ width: 7, height: 7, borderRadius: "50%", background: color }} />
        {label}
      </span>
    </div>
  );
}

function Metric({ label, value }: { label: string; value: string | number }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 4, minWidth: 0 }}>
      <span style={metricLabel}>{label}</span>
      <span style={{
        fontSize: 13, color: INK.ink, fontFamily: INK.fontSans, fontWeight: 500,
        overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
      }}>
        {value}
      </span>
    </div>
  );
}

function TileLoader({ label }: { label: string }) {
  return (
    <div style={{
      display: "flex", alignItems: "center", justifyContent: "center",
      gap: 8, padding: "32px 0", color: INK.muted, fontSize: 13,
      fontFamily: INK.fontSans,
    }}>
      <Loader2 className="animate-spin" size={14} /> {label}
    </div>
  );
}

function TileEmpty({
  icon,
  title,
  subtitle,
}: {
  icon: React.ReactNode;
  title: string;
  subtitle: string;
}) {
  return (
    <div style={{
      padding: "28px 8px",
      textAlign: "center",
      display: "flex", flexDirection: "column", alignItems: "center", gap: 10,
      fontFamily: INK.fontSans,
    }}>
      <span style={{ ...tileIconWrap, width: 38, height: 38 }}>{icon}</span>
      <div style={{ fontSize: 13.5, fontWeight: 600, color: INK.ink }}>{title}</div>
      <div style={{ fontSize: 12.5, color: INK.muted, lineHeight: 1.55, maxWidth: 280 }}>
        {subtitle}
      </div>
    </div>
  );
}

function statusFriendly(status: string): string {
  if (!status || status === "unknown") return "Unknown";
  return status.replace(/[:_-]+/g, " ").replace(/\b\w/g, c => c.toUpperCase());
}

function ext(name: string): string {
  const dot = name.lastIndexOf(".");
  return dot > 0 ? name.slice(dot + 1) : "file";
}

function shortUrl(url: string): string {
  try {
    const u = new URL(url);
    return u.host + (u.pathname === "/" ? "" : u.pathname);
  } catch {
    return url;
  }
}

function hoverEnter(e: React.MouseEvent<HTMLElement>) {
  const el = e.currentTarget;
  el.style.borderColor = INK.borderHover;
  el.style.boxShadow = INK.shadowHover;
}
function hoverLeave(e: React.MouseEvent<HTMLElement>) {
  const el = e.currentTarget;
  el.style.borderColor = INK.border;
  el.style.boxShadow = INK.shadow;
}

// ──────────────────────────────────────────────────────────────────────
// Styles
// ──────────────────────────────────────────────────────────────────────

const pageWrap: React.CSSProperties = {
  flex: 1,
  minHeight: 0,
  overflow: "auto",
  background: INK.pageBg,
  fontFamily: INK.fontSans,
};

const pageInner: React.CSSProperties = {
  maxWidth: 900,
  margin: "0 auto",
  padding: "44px 52px 64px",
  display: "flex",
  flexDirection: "column",
  gap: 28,
};

const centeredFiller: React.CSSProperties = {
  display: "flex", alignItems: "center", justifyContent: "center",
  height: "100%", padding: 64,
};

const heroStyle: React.CSSProperties = {
  display: "flex", alignItems: "flex-start", justifyContent: "space-between",
  gap: 24,
};

const eyebrow: React.CSSProperties = {
  fontSize: "0.68rem", fontWeight: 600, letterSpacing: "0.12em",
  textTransform: "uppercase", color: INK.muted,
  fontFamily: INK.fontSans, marginBottom: 8,
};

const heroTitle: React.CSSProperties = {
  fontFamily: INK.fontSerif,
  fontSize: "1.9rem", fontWeight: 400,
  color: INK.ink, letterSpacing: "-0.03em",
  lineHeight: 1.15, margin: 0,
};

const heroDesc: React.CSSProperties = {
  fontSize: "0.88rem", color: INK.mid, marginTop: 10, maxWidth: 620,
  lineHeight: 1.6, fontFamily: INK.fontSans,
};

const continueRow: React.CSSProperties = {
  display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16,
  background: INK.cardBg, border: `1px solid ${INK.border}`,
  borderRadius: 10, padding: "14px 18px",
  textDecoration: "none", color: "inherit",
  boxShadow: INK.shadow,
  fontFamily: INK.fontSans,
  transition: "border-color 0.15s, box-shadow 0.15s",
};

const continueDot: React.CSSProperties = {
  width: 7, height: 7, borderRadius: "50%",
  background: "#d4a04a", flexShrink: 0,
};

const continueTitle: React.CSSProperties = {
  fontSize: 13, fontWeight: 600, color: INK.ink,
};

const continueSub: React.CSSProperties = {
  fontSize: 12, color: INK.muted, marginTop: 2,
};

const tileGrid: React.CSSProperties = {
  display: "grid",
  gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))",
  gap: 14,
};

const tileLink: React.CSSProperties = {
  textDecoration: "none", color: "inherit",
};

const tileCard: React.CSSProperties = {
  background: INK.cardBg,
  border: `1px solid ${INK.border}`,
  borderRadius: 10,
  padding: 22,
  display: "flex", flexDirection: "column", gap: 18,
  minHeight: 280,
  boxShadow: INK.shadow,
  transition: "border-color 0.15s, box-shadow 0.15s",
  fontFamily: INK.fontSans,
};

const tileHeader: React.CSSProperties = {
  display: "flex", alignItems: "center", gap: 12,
};

const tileIconWrap: React.CSSProperties = {
  width: 32, height: 32, borderRadius: 8,
  background: INK.iconWrapBg, color: INK.ink,
  display: "flex", alignItems: "center", justifyContent: "center",
  flexShrink: 0,
};

const tileTitle: React.CSSProperties = {
  fontFamily: INK.fontSerif,
  fontSize: "1.05rem", fontWeight: 400,
  color: INK.ink, letterSpacing: "-0.02em",
  margin: 0, lineHeight: 1.2,
};

const tileSubtitle: React.CSSProperties = {
  fontSize: 12, color: INK.muted, marginTop: 3,
  fontFamily: INK.fontSans,
};

const tileBody: React.CSSProperties = {
  display: "flex", flexDirection: "column", gap: 14, flex: 1, minHeight: 0,
};

const tileMetaRow: React.CSSProperties = {
  display: "flex", gap: 28,
};

const metricLabel: React.CSSProperties = {
  fontSize: "0.62rem", fontWeight: 600, letterSpacing: "0.1em",
  textTransform: "uppercase", color: INK.muted,
  fontFamily: INK.fontSans,
};

const fileList: React.CSSProperties = {
  listStyle: "none", padding: 0, margin: 0,
  display: "flex", flexDirection: "column",
  border: `1px solid ${INK.border}`, borderRadius: 8,
  overflow: "hidden",
  background: "#fdfcfa",
};

const fileRow: React.CSSProperties = {
  display: "flex", alignItems: "center", gap: 10,
  padding: "8px 12px",
  borderTop: `1px solid ${INK.border}`,
  fontSize: 12.5, color: INK.ink,
};

const fileIconWrap: React.CSSProperties = {
  color: INK.stone, display: "flex", alignItems: "center",
};

const fileName: React.CSSProperties = {
  flex: 1, minWidth: 0, overflow: "hidden",
  textOverflow: "ellipsis", whiteSpace: "nowrap",
  fontFamily: INK.fontMono, fontSize: 12,
};

const fileType: React.CSSProperties = {
  fontSize: 10, color: INK.stone, fontWeight: 500,
  textTransform: "uppercase", letterSpacing: "0.08em",
  flexShrink: 0, fontFamily: INK.fontSans,
};

const tileMore: React.CSSProperties = {
  fontSize: 11.5, color: INK.muted, paddingLeft: 4,
  fontFamily: INK.fontSans,
};

const liveUrlRow: React.CSSProperties = {
  display: "flex", alignItems: "center", gap: 10,
  padding: "10px 12px",
  background: "#fdfcfa",
  border: `1px solid ${INK.border}`,
  borderRadius: 8,
};

const liveUrlLabel: React.CSSProperties = {
  fontSize: "0.62rem", fontWeight: 600, letterSpacing: "0.1em",
  textTransform: "uppercase", color: INK.muted,
  flexShrink: 0, fontFamily: INK.fontSans,
};

const liveUrlValue: React.CSSProperties = {
  flex: 1, minWidth: 0,
  fontSize: 12, color: INK.ink, fontWeight: 500,
  overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
  fontFamily: INK.fontMono,
};

const liveUrlOpen: React.CSSProperties = {
  width: 24, height: 24, borderRadius: 6,
  display: "flex", alignItems: "center", justifyContent: "center",
  color: INK.ink, background: INK.cardBg,
  border: `1px solid ${INK.border}`, flexShrink: 0,
  textDecoration: "none",
};
