import { useState, useEffect, useCallback } from "react";
import type { Project, ProjectWithTasks, Task } from "../lib/types";
import {
  fetchProjects,
  fetchProject,
  createProject,
  updateProject,
  updateTask,
} from "../lib/api";

// ─── Status/priority helpers ───
const statusColors: Record<string, string> = {
  active: "bg-green-100 text-green-700",
  queued: "bg-blue-100 text-blue-700",
  blocked: "bg-red-100 text-red-700",
  completed: "bg-gray-100 text-gray-500",
  cancelled: "bg-gray-100 text-gray-400",
};

function StatusBadge({ status }: { status: string }) {
  return (
    <span
      className={`text-[10px] font-semibold px-1.5 py-0.5 rounded-full uppercase ${statusColors[status] || "bg-gray-100 text-gray-500"}`}
    >
      {status}
    </span>
  );
}

// ─── Create Project Modal ───
function CreateProjectModal({
  onClose,
  onCreated,
}: {
  onClose: () => void;
  onCreated: (p: Project) => void;
}) {
  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [context, setContext] = useState("");
  const [repos, setRepos] = useState("");
  const [saving, setSaving] = useState(false);

  const handleSave = async () => {
    if (!name.trim()) return;
    setSaving(true);
    try {
      const repoList = repos
        .split("\n")
        .map((r) => r.trim())
        .filter(Boolean);
      const project = await createProject({
        name: name.trim(),
        description: description.trim() || undefined,
        context: context.trim() || undefined,
        repos: repoList.length ? repoList : undefined,
      });
      onCreated(project);
    } catch (e) {
      console.error(e);
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="fixed inset-0 bg-black/40 z-50 flex items-center justify-center p-4">
      <div className="bg-white rounded-xl shadow-xl w-full max-w-lg max-h-[90vh] overflow-y-auto">
        <div className="px-6 py-4 border-b border-gray-100">
          <h2 className="text-lg font-bold text-gray-900">New Project</h2>
        </div>
        <div className="px-6 py-4 space-y-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Name *
            </label>
            <input
              value={name}
              onChange={(e) => setName(e.target.value)}
              className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-amber-200"
              placeholder="e.g. Hammer Dashboard"
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Description
            </label>
            <textarea
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              rows={2}
              className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-amber-200 resize-none"
              placeholder="Brief description of the project"
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Context{" "}
              <span className="text-gray-400 font-normal">
                (architecture, credentials refs, how-to)
              </span>
            </label>
            <textarea
              value={context}
              onChange={(e) => setContext(e.target.value)}
              rows={5}
              className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-amber-200 resize-none"
              placeholder={`Repo: https://gitea.donovankelly.xyz/...\nDomain: dash.donovankelly.xyz\nDokploy Compose ID: ...\nStack: React + Vite, Elysia + Bun, Postgres + Drizzle`}
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Repos{" "}
              <span className="text-gray-400 font-normal">(one per line)</span>
            </label>
            <textarea
              value={repos}
              onChange={(e) => setRepos(e.target.value)}
              rows={2}
              className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-amber-200 resize-none"
              placeholder="https://gitea.donovankelly.xyz/donovan/hammer-queue"
            />
          </div>
        </div>
        <div className="px-6 py-3 border-t border-gray-100 flex justify-end gap-2">
          <button
            onClick={onClose}
            className="px-4 py-2 text-sm text-gray-600 hover:text-gray-800 transition"
          >
            Cancel
          </button>
          <button
            onClick={handleSave}
            disabled={!name.trim() || saving}
            className="px-4 py-2 text-sm bg-amber-500 text-white rounded-lg hover:bg-amber-600 disabled:opacity-50 transition font-medium"
          >
            {saving ? "Creating..." : "Create Project"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ─── Project Detail View ───
function ProjectDetail({
  projectId,
  onBack,
  allTasks,
  onTasksChanged,
}: {
  projectId: string;
  onBack: () => void;
  allTasks: Task[];
  onTasksChanged: () => void;
}) {
  const [project, setProject] = useState<ProjectWithTasks | null>(null);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState(false);
  const [editName, setEditName] = useState("");
  const [editDesc, setEditDesc] = useState("");
  const [editContext, setEditContext] = useState("");
  const [editRepos, setEditRepos] = useState("");
  const [saving, setSaving] = useState(false);
  const [showAssign, setShowAssign] = useState(false);

  const load = useCallback(async () => {
    try {
      const data = await fetchProject(projectId);
      setProject(data);
    } catch (e) {
      console.error(e);
    } finally {
      setLoading(false);
    }
  }, [projectId]);

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

  const startEdit = () => {
    if (!project) return;
    setEditName(project.name);
    setEditDesc(project.description || "");
    setEditContext(project.context || "");
    setEditRepos((project.repos || []).join("\n"));
    setEditing(true);
  };

  const saveEdit = async () => {
    if (!project) return;
    setSaving(true);
    try {
      const repoList = editRepos
        .split("\n")
        .map((r) => r.trim())
        .filter(Boolean);
      await updateProject(project.id, {
        name: editName.trim(),
        description: editDesc.trim() || null,
        context: editContext.trim() || null,
        repos: repoList,
      });
      setEditing(false);
      load();
    } catch (e) {
      console.error(e);
    } finally {
      setSaving(false);
    }
  };

  const assignTask = async (taskId: string) => {
    try {
      await updateTask(taskId, { projectId });
      load();
      onTasksChanged();
    } catch (e) {
      console.error(e);
    }
  };

  const unassignTask = async (taskId: string) => {
    try {
      await updateTask(taskId, { projectId: null });
      load();
      onTasksChanged();
    } catch (e) {
      console.error(e);
    }
  };

  if (loading) {
    return (
      <div className="p-8 text-center text-gray-400">Loading project...</div>
    );
  }

  if (!project) {
    return (
      <div className="p-8 text-center text-gray-400">Project not found</div>
    );
  }

  // Unassigned tasks (not in this project)
  const unassignedTasks = allTasks.filter(
    (t) =>
      !t.projectId &&
      t.status !== "completed" &&
      t.status !== "cancelled"
  );

  return (
    <div className="max-w-4xl mx-auto">
      {/* Header */}
      <div className="flex items-center gap-3 mb-6">
        <button
          onClick={onBack}
          className="p-1.5 rounded-lg hover:bg-gray-100 transition text-gray-400"
        >
          <svg
            className="w-5 h-5"
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              d="M15 19l-7-7 7-7"
            />
          </svg>
        </button>
        <div className="flex-1">
          {editing ? (
            <input
              value={editName}
              onChange={(e) => setEditName(e.target.value)}
              className="text-2xl font-bold text-gray-900 border-b-2 border-amber-400 focus:outline-none w-full"
            />
          ) : (
            <h1 className="text-2xl font-bold text-gray-900">
              {project.name}
            </h1>
          )}
        </div>
        {!editing && (
          <button
            onClick={startEdit}
            className="text-xs text-amber-600 hover:text-amber-700 font-medium px-3 py-1.5 rounded-lg hover:bg-amber-50 transition"
          >
            Edit
          </button>
        )}
      </div>

      {/* Edit mode */}
      {editing ? (
        <div className="bg-white rounded-xl border border-gray-200 p-6 mb-6 space-y-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Description
            </label>
            <textarea
              value={editDesc}
              onChange={(e) => setEditDesc(e.target.value)}
              rows={2}
              className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-amber-200 resize-none"
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Context
            </label>
            <textarea
              value={editContext}
              onChange={(e) => setEditContext(e.target.value)}
              rows={8}
              className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-amber-200 resize-none"
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Repos (one per line)
            </label>
            <textarea
              value={editRepos}
              onChange={(e) => setEditRepos(e.target.value)}
              rows={2}
              className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-amber-200 resize-none"
            />
          </div>
          <div className="flex gap-2 justify-end">
            <button
              onClick={() => setEditing(false)}
              className="px-4 py-2 text-sm text-gray-600 hover:text-gray-800"
            >
              Cancel
            </button>
            <button
              onClick={saveEdit}
              disabled={saving || !editName.trim()}
              className="px-4 py-2 text-sm bg-amber-500 text-white rounded-lg hover:bg-amber-600 disabled:opacity-50 font-medium"
            >
              {saving ? "Saving..." : "Save"}
            </button>
          </div>
        </div>
      ) : (
        <>
          {/* Description */}
          {project.description && (
            <p className="text-sm text-gray-600 mb-4">{project.description}</p>
          )}

          {/* Context card */}
          {project.context && (
            <div className="bg-gray-50 rounded-xl border border-gray-200 p-5 mb-6">
              <h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2">
                📋 Context
              </h3>
              <pre className="text-sm text-gray-700 whitespace-pre-wrap font-mono leading-relaxed">
                {project.context}
              </pre>
            </div>
          )}

          {/* Repos */}
          {project.repos && project.repos.length > 0 && (
            <div className="mb-6">
              <h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2">
                📦 Repos
              </h3>
              <div className="space-y-1">
                {project.repos.map((repo, i) => (
                  <a
                    key={i}
                    href={repo}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="block text-sm text-blue-600 hover:text-blue-800 font-mono truncate"
                  >
                    {repo}
                  </a>
                ))}
              </div>
            </div>
          )}

          {/* Links */}
          {project.links && project.links.length > 0 && (
            <div className="mb-6">
              <h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2">
                🔗 Links
              </h3>
              <div className="space-y-1">
                {project.links.map((link, i) => (
                  <a
                    key={i}
                    href={link.url}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="block text-sm text-blue-600 hover:text-blue-800"
                  >
                    {link.label}{" "}
                    <span className="text-gray-400 font-mono text-xs">
                      ({link.url})
                    </span>
                  </a>
                ))}
              </div>
            </div>
          )}
        </>
      )}

      {/* Tasks section */}
      <div className="mt-6">
        <div className="flex items-center justify-between mb-3">
          <h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide">
            📝 Tasks ({project.tasks?.length || 0})
          </h3>
          <button
            onClick={() => setShowAssign(!showAssign)}
            className="text-xs text-amber-600 hover:text-amber-700 font-medium px-2 py-1 rounded hover:bg-amber-50 transition"
          >
            {showAssign ? "Done" : "+ Assign Task"}
          </button>
        </div>

        {/* Assign task dropdown */}
        {showAssign && unassignedTasks.length > 0 && (
          <div className="bg-white rounded-xl border border-amber-200 p-3 mb-4 max-h-48 overflow-y-auto">
            <p className="text-xs text-gray-400 mb-2">
              Select a task to assign to this project:
            </p>
            {unassignedTasks.map((task) => (
              <button
                key={task.id}
                onClick={() => assignTask(task.id)}
                className="w-full text-left px-3 py-2 text-sm text-gray-700 hover:bg-amber-50 rounded-lg transition flex items-center gap-2"
              >
                <span className="text-gray-400 text-xs font-mono">
                  HQ-{task.taskNumber}
                </span>
                <span className="truncate">{task.title}</span>
                <StatusBadge status={task.status} />
              </button>
            ))}
          </div>
        )}
        {showAssign && unassignedTasks.length === 0 && (
          <div className="bg-gray-50 rounded-lg p-3 mb-4 text-xs text-gray-400 text-center">
            All tasks are already assigned to projects
          </div>
        )}

        {/* Task list */}
        {project.tasks && project.tasks.length > 0 ? (
          <div className="space-y-2">
            {project.tasks.map((task) => (
              <div
                key={task.id}
                className="bg-white rounded-lg border border-gray-200 px-4 py-3 flex items-center gap-3"
              >
                <span className="text-xs text-gray-400 font-mono shrink-0">
                  HQ-{task.taskNumber}
                </span>
                <span className="text-sm text-gray-800 flex-1 truncate">
                  {task.title}
                </span>
                <StatusBadge status={task.status} />
                <button
                  onClick={() => unassignTask(task.id)}
                  className="text-gray-300 hover:text-red-400 transition shrink-0"
                  title="Remove from project"
                >
                  <svg
                    className="w-4 h-4"
                    fill="none"
                    stroke="currentColor"
                    viewBox="0 0 24 24"
                  >
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2}
                      d="M6 18L18 6M6 6l12 12"
                    />
                  </svg>
                </button>
              </div>
            ))}
          </div>
        ) : (
          <div className="text-sm text-gray-400 text-center py-6 bg-gray-50 rounded-lg">
            No tasks assigned to this project yet
          </div>
        )}
      </div>
    </div>
  );
}

// ─── Project Card ───
function ProjectCard({
  project,
  taskCount,
  onClick,
}: {
  project: Project;
  taskCount: number;
  onClick: () => void;
}) {
  return (
    <button
      onClick={onClick}
      className="w-full text-left bg-white rounded-xl border border-gray-200 p-5 hover:border-amber-300 hover:shadow-sm transition group"
    >
      <div className="flex items-start justify-between mb-2">
        <h3 className="text-base font-semibold text-gray-900 group-hover:text-amber-700 transition">
          {project.name}
        </h3>
        <span className="text-xs text-gray-400 bg-gray-100 px-2 py-0.5 rounded-full shrink-0 ml-2">
          {taskCount} task{taskCount !== 1 ? "s" : ""}
        </span>
      </div>
      {project.description && (
        <p className="text-sm text-gray-500 line-clamp-2 mb-3">
          {project.description}
        </p>
      )}
      <div className="flex items-center gap-3">
        {project.repos && project.repos.length > 0 && (
          <span className="text-xs text-gray-400">
            📦 {project.repos.length} repo
            {project.repos.length !== 1 ? "s" : ""}
          </span>
        )}
        {project.context && (
          <span className="text-xs text-gray-400">📋 Has context</span>
        )}
      </div>
    </button>
  );
}

// ─── Main Page ───
export function ProjectsPage() {
  const [projects, setProjects] = useState<Project[]>([]);
  const [allTasks, setAllTasks] = useState<Task[]>([]);
  const [loading, setLoading] = useState(true);
  const [showCreate, setShowCreate] = useState(false);
  const [selectedProject, setSelectedProject] = useState<string | null>(null);

  const loadAll = useCallback(async () => {
    try {
      const [projectsData, tasksRes] = await Promise.all([
        fetchProjects(),
        fetch("/api/tasks", { credentials: "include" }).then((r) => r.json()),
      ]);
      setProjects(projectsData);
      setAllTasks(tasksRes);
    } catch (e) {
      console.error(e);
    } finally {
      setLoading(false);
    }
  }, []);

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

  // Count tasks per project
  const taskCountMap: Record<string, number> = {};
  for (const task of allTasks) {
    if (task.projectId) {
      taskCountMap[task.projectId] = (taskCountMap[task.projectId] || 0) + 1;
    }
  }

  if (selectedProject) {
    return (
      <div className="p-4 sm:p-6">
        <ProjectDetail
          projectId={selectedProject}
          onBack={() => {
            setSelectedProject(null);
            loadAll();
          }}
          allTasks={allTasks}
          onTasksChanged={loadAll}
        />
      </div>
    );
  }

  return (
    <div className="p-4 sm:p-6">
      {/* Header */}
      <div className="flex items-center justify-between mb-6">
        <div>
          <h1 className="text-xl sm:text-2xl font-bold text-gray-900">
            Projects
          </h1>
          <p className="text-sm text-gray-500 mt-1">
            Organize tasks by project with context for autonomous work
          </p>
        </div>
        <button
          onClick={() => setShowCreate(true)}
          className="px-4 py-2 bg-amber-500 text-white rounded-lg text-sm font-medium hover:bg-amber-600 transition"
        >
          + New Project
        </button>
      </div>

      {loading ? (
        <div className="text-center text-gray-400 py-12">
          Loading projects...
        </div>
      ) : projects.length === 0 ? (
        <div className="text-center py-16">
          <span className="text-5xl block mb-4">📁</span>
          <h2 className="text-lg font-semibold text-gray-600 mb-2">
            No projects yet
          </h2>
          <p className="text-sm text-gray-400 mb-4">
            Create a project to group tasks and add context
          </p>
          <button
            onClick={() => setShowCreate(true)}
            className="px-4 py-2 bg-amber-500 text-white rounded-lg text-sm font-medium hover:bg-amber-600 transition"
          >
            Create First Project
          </button>
        </div>
      ) : (
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {projects.map((project) => (
            <ProjectCard
              key={project.id}
              project={project}
              taskCount={taskCountMap[project.id] || 0}
              onClick={() => setSelectedProject(project.id)}
            />
          ))}
        </div>
      )}

      {showCreate && (
        <CreateProjectModal
          onClose={() => setShowCreate(false)}
          onCreated={(p) => {
            setShowCreate(false);
            setProjects((prev) => [...prev, p]);
          }}
        />
      )}
    </div>
  );
}
