import { useCallback, useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";

import { getDashboardSummary, type DashboardSummary } from "../api/dashboard";
import { createInstance, getUserSessions, startInstance, stopInstance, deleteInstance, recreateInstanceTunnel, type Session as SessionApi } from "../api/sessions";
import { listProjects } from "../api/projects";
import { listRepositories, type GitRepository } from "../api/git_repositories";
import { listToolTypes, type ToolType } from "../api/tool_types";
import { updateUserConfig } from "../api/settings";
import type { Project } from "../types";
import { Icon } from "../components/icon";

type HomeStatus = "loading" | "ready" | "error";

const summaryCards = [
  { label: "Open sessions", key: "openSessions" },
  { label: "Projects", key: "projects" },
  { label: "Repositories", key: "repositories" },
] as const;

type SessionView = SessionApi;

export const HomePage = () => {
  const navigate = useNavigate();
  const [status, setStatus] = useState<HomeStatus>("loading");
  const [summary, setSummary] = useState<DashboardSummary | null>(null);
  const [sessions, setSessions] = useState<SessionView[]>([]);
  const [projects, setProjects] = useState<Project[]>([]);
  const [repositories, setRepositories] = useState<GitRepository[]>([]);
  const [toolTypes, setToolTypes] = useState<ToolType[]>([]);
  const [selectedProject, setSelectedProject] = useState("");
  const [selectedRepo, setSelectedRepo] = useState("");
  const [selectedToolType, setSelectedToolType] = useState("");
  const [displayName, setDisplayName] = useState("");
  const [saveState, setSaveState] = useState<"idle" | "saving" | "error">("idle");
  const [actionBusy, setActionBusy] = useState<string | null>(null);
  const safeSessions = Array.isArray(sessions) ? sessions : [];

  const loadHome = useCallback(async () => {
    setStatus("loading");
    try {
      const [dashboard, sessionData, projectData, toolTypeData] = await Promise.all([
        getDashboardSummary(),
        getUserSessions(),
        listProjects(),
        listToolTypes(),
      ]);
      setSummary(dashboard);
      setSessions(sessionData as SessionView[]);
      setProjects(projectData);
      setToolTypes(toolTypeData);
      setStatus("ready");
    } catch {
      setStatus("error");
    }
  }, []);

  useEffect(() => {
    void loadHome();
  }, [loadHome]);

  useEffect(() => {
    if (!selectedProject) {
      setRepositories([]);
      return;
    }

    const loadRepos = async () => {
      try {
        const data = await listRepositories(selectedProject);
        setRepositories(data);
      } catch {
        setRepositories([]);
      }
    };

    void loadRepos();
  }, [selectedProject]);

  const activeSessions = useMemo(
    () => safeSessions.filter((session) => ["running", "building", "pending"].includes(session.status)),
    [safeSessions]
  );

  const recentSessions = useMemo(
    () => safeSessions.filter((session) => ["stopped", "error"].includes(session.status)).slice(0, 5),
    [safeSessions]
  );

  const handleCreate = async (event: React.FormEvent) => {
    event.preventDefault();
    if (!selectedProject || !selectedRepo || !selectedToolType) return;

    setSaveState("saving");
    try {
      const instance = await createInstance(selectedProject, selectedRepo, selectedToolType, displayName || undefined);
      await startInstance(selectedProject, selectedRepo, instance.id);
      await updateUserConfig({ last_session_id: instance.id });
      setDisplayName("");
      setSelectedProject("");
      setSelectedRepo("");
      setSelectedToolType("");
      setSaveState("idle");
      await loadHome();
    } catch {
      setSaveState("error");
    }
  };

  const handleOpen = (session: SessionView) => {
    if (session.url) {
      window.open(session.url, "_blank", "noopener,noreferrer");
      return;
    }
    if (session.tool_type_interfaces.includes("terminal")) {
      navigate(`/instances/${session.id}/terminal`);
      return;
    }
    navigate(`/projects/${session.project_id}`);
  };

  const handleStop = async (session: SessionView) => {
    setActionBusy(session.id);
    try {
      await stopInstance(session.project_id, session.repository_id, session.id);
      await loadHome();
    } finally {
      setActionBusy(null);
    }
  };

  const handleDelete = async (session: SessionView) => {
    setActionBusy(session.id);
    try {
      await deleteInstance(session.project_id, session.repository_id, session.id);
      await loadHome();
    } finally {
      setActionBusy(null);
    }
  };

  const handleRecreateTunnel = async (session: SessionView) => {
    setActionBusy(session.id);
    try {
      await recreateInstanceTunnel(session.project_id, session.repository_id, session.id);
      await loadHome();
    } finally {
      setActionBusy(null);
    }
  };

  return (
    <section className="stack home-page">
      <header className="home-hero card">
        <div className="stack-sm">
          <p className="eyebrow">Workspace overview</p>
          <h1>Home</h1>
          <p className="muted">Open sessions, available projects, and the fastest path back into work.</p>
        </div>
        <div className="home-hero-actions">
          <button className="primary-button" type="button" onClick={() => navigate("/projects")}>New Project</button>
          <button className="secondary-button" type="button" onClick={() => navigate("/settings")}>Settings</button>
        </div>
      </header>

      {status === "loading" && <p className="muted">Loading overview...</p>}

      {status === "error" && (
        <div className="card stack">
          <p>Unable to load your workspace overview.</p>
          <button className="secondary-button" type="button" onClick={() => void loadHome()}>
            <Icon name="refresh" size="sm" />
            Retry
          </button>
        </div>
      )}

      {status === "ready" && summary && (
        <>
          <div className="home-summary-grid">
            {summaryCards.map((card) => (
              <article className="card home-summary-card" key={card.label}>
                <p className="card-label">{card.label}</p>
                <p className="card-value">
                  {card.key === "openSessions"
                    ? activeSessions.length
                    : card.key === "projects"
                      ? summary.projects
                      : summary.repositories}
                </p>
              </article>
            ))}
          </div>

          <section className="card stack home-section">
            <div className="page-header">
              <div>
                <p className="eyebrow">Open sessions</p>
                <h2>{activeSessions.length}</h2>
              </div>
            </div>
            {activeSessions.length === 0 ? (
              <p className="muted">No active sessions right now.</p>
            ) : (
              <div className="home-session-grid">
                {activeSessions.map((session) => (
                  <article className="card session-card" key={session.id}>
                    <div className="stack-sm">
                      <div className="row row-tight">
                        <h3>{session.display_name}</h3>
                        <span className={`status-badge ${session.status}`}>{session.status}</span>
                      </div>
                      <p className="muted">{session.project_name} · {session.repository_name}</p>
                      <p className="muted">{session.tool_type_name}</p>
                    </div>
                    <div className="session-actions">
                      <button className="secondary-button small" type="button" onClick={() => handleOpen(session)}>
                        <Icon name="external" size="sm" />
                        Open
                      </button>
                      <button className="ghost-button small" type="button" onClick={() => void handleRecreateTunnel(session)} disabled={actionBusy === session.id}>
                        <Icon name="refresh" size="sm" />
                        Tunnel
                      </button>
                      <button className="ghost-button small" type="button" onClick={() => void handleStop(session)} disabled={actionBusy === session.id}>
                        <Icon name="stop" size="sm" />
                        Stop
                      </button>
                      <button className="ghost-button small danger-text" type="button" onClick={() => void handleDelete(session)} disabled={actionBusy === session.id}>
                        <Icon name="delete" size="sm" />
                        Delete
                      </button>
                    </div>
                  </article>
                ))}
              </div>
            )}
          </section>

          <section className="card stack home-section">
            <div className="page-header">
              <div>
                <p className="eyebrow">Available projects</p>
                <h2>{projects.length}</h2>
              </div>
              <button className="secondary-button" type="button" onClick={() => navigate("/projects")}>View all</button>
            </div>
            {projects.length === 0 ? (
              <p className="muted">No projects yet.</p>
            ) : (
              <div className="home-project-grid">
                {projects.map((project) => (
                  <article className="card project-card home-project-card" key={project.id}>
                    <div className="stack-sm">
                      <h3>{project.name}</h3>
                      {project.description && <p className="muted">{project.description}</p>}
                    </div>
                    <button className="ghost-button small" type="button" onClick={() => navigate(`/projects/${project.id}`)}>
                      Open Workspace
                    </button>
                  </article>
                ))}
              </div>
            )}
          </section>

          <section className="card stack home-section">
            <div className="page-header">
              <div>
                <p className="eyebrow">Quick create</p>
                <h2>Start a session</h2>
              </div>
            </div>
            <form className="stack create-session-form" onSubmit={handleCreate}>
              <div className="form-row">
                <label className="form-field">
                  Project
                  <select value={selectedProject} onChange={(event) => { setSelectedProject(event.target.value); setSelectedRepo(""); }}>
                    <option value="">Select project...</option>
                    {projects.map((project) => <option key={project.id} value={project.id}>{project.name}</option>)}
                  </select>
                </label>
                <label className="form-field">
                  Repository
                  <select value={selectedRepo} onChange={(event) => setSelectedRepo(event.target.value)} disabled={!selectedProject}>
                    <option value="">Select repository...</option>
                    {repositories.map((repo) => <option key={repo.id} value={repo.id}>{repo.name}</option>)}
                  </select>
                </label>
                <label className="form-field">
                  Tool type
                  <select value={selectedToolType} onChange={(event) => setSelectedToolType(event.target.value)}>
                    <option value="">Select tool...</option>
                  {toolTypes.map((tool) => <option key={tool.id} value={tool.id}>{tool.display_name}</option>)}
                </select>
              </label>
              </div>
              <label className="form-field">
                Display name
                <input type="text" value={displayName} onChange={(event) => setDisplayName(event.target.value)} placeholder="My Development Environment" />
              </label>
              <div className="form-actions">
                <button className="primary-button" type="submit" disabled={saveState === "saving"}>
                  {saveState === "saving" ? <><Icon name="loading" size="sm" /> Creating...</> : <><Icon name="add" size="sm" /> Create Session</>}
                </button>
                {saveState === "error" && <span className="error-text">Failed to create session</span>}
              </div>
            </form>
          </section>

          {recentSessions.length > 0 && (
            <section className="card stack home-section">
              <div className="page-header">
                <div>
                  <p className="eyebrow">Recent sessions</p>
                  <h2>{recentSessions.length}</h2>
                </div>
              </div>
              <div className="recent-sessions-list">
                {recentSessions.map((session) => (
                  <article className="recent-session-item" key={session.id}>
                    <div className="recent-session-info">
                      <span className="recent-session-name">{session.display_name}</span>
                      <span className="muted">{session.project_name} · {session.tool_type_name}</span>
                    </div>
                    <button className="ghost-button small" type="button" onClick={() => handleOpen(session)}>Open</button>
                  </article>
                ))}
              </div>
            </section>
          )}
        </>
      )}
    </section>
  );
};

export { HomePage as DashboardPage };
