'use client';

import { AnimatePresence, motion } from 'motion/react';
import Link from 'next/link';
import { useRouter, useSearchParams } from 'next/navigation';
import { useCallback, useMemo, useState } from 'react';
import { toast } from 'sonner';
import { EditableTags, EditableText } from '@/components/editable';
import { ROUTE_CONFIG, useSetBreadcrumb } from '@/components/layout/breadcrumb';
import { PageHeader } from '@/components/layout/page-header';
import { VelocityLineChart } from '@/components/metrics/charts';
import { CreateProjectDialog } from '@/components/projects/create-project-dialog';
import { ProjectsEmptyState } from '@/components/ui/empty-state';
import {
  AlertTriangle,
  Archive,
  ArrowDownAZ,
  BarChart3,
  CheckCircle2,
  Clock,
  FolderKanban,
  GitBranch,
  Pause,
  Plus,
  Trash,
  TrendingUp,
  User,
  Users,
  Zap,
} from '@/components/ui/icons';
import { Spinner } from '@/components/ui/spinner';
import { ErrorState, Tooltip } from '@/components/ui/tooltip';
import type {
  ProjectRole,
  ProjectSummariesResponse,
  ProjectSummary,
  TaskListResponse,
  TaskStatus,
  TaskSummary,
} from '@/lib/api';
import { TASK_STATUS_CONFIG } from '@/lib/constants';
import {
  useDeleteEntity,
  useMe,
  useProjectMembers,
  useProjectMetrics,
  useProjectSummaries,
  useProjects,
  useRemoveProjectMember,
  useTasks,
  useUpdateEntity,
  useUpdateProjectMemberRole,
} from '@/lib/hooks';
import { useClientPrefs } from '@/lib/storage';

interface ProjectsContentProps {
  initialProjects: TaskListResponse;
  initialProjectSummaries?: ProjectSummariesResponse;
}

// Project sort options
type ProjectSortOption = 'active' | 'name' | 'tasks' | 'completion' | 'urgent';

const PROJECT_SORT_OPTIONS: Array<{
  value: ProjectSortOption;
  label: string;
  icon: React.ReactNode;
}> = [
  { value: 'active', label: 'Most Active', icon: <TrendingUp width={14} height={14} /> },
  { value: 'urgent', label: 'Urgent First', icon: <Zap width={14} height={14} /> },
  { value: 'tasks', label: 'Most Tasks', icon: <BarChart3 width={14} height={14} /> },
  { value: 'completion', label: 'Completion %', icon: <CheckCircle2 width={14} height={14} /> },
  { value: 'name', label: 'Name', icon: <ArrowDownAZ width={14} height={14} /> },
];

interface ProjectStats {
  total: number;
  done: number;
  doing: number;
  blocked: number;
  review: number;
  todo: number;
  backlog: number;
  critical: number;
  high: number;
  overdue: number;
}

function projectStatsFromSummary(summary?: ProjectSummary): ProjectStats {
  return {
    total: summary?.total ?? 0,
    done: summary?.completed ?? 0,
    doing: summary?.doing ?? 0,
    blocked: summary?.blocked ?? 0,
    review: summary?.review ?? 0,
    todo: summary?.todo ?? 0,
    backlog: summary?.backlog ?? 0,
    critical: summary?.critical ?? 0,
    high: summary?.high ?? 0,
    overdue: summary?.overdue ?? 0,
  };
}

interface ProjectsPrefs {
  sortBy: ProjectSortOption;
  showArchived: boolean;
}

export function ProjectsContent({
  initialProjects,
  initialProjectSummaries,
}: ProjectsContentProps) {
  const router = useRouter();
  const searchParams = useSearchParams();

  // Persisted preferences
  const [prefs, setPrefs] = useClientPrefs<ProjectsPrefs>({
    key: 'projects:prefs',
    defaultValue: { sortBy: 'active', showArchived: false },
  });
  const { sortBy, showArchived } = prefs;
  const setSortBy = (v: ProjectSortOption) => setPrefs(p => ({ ...p, sortBy: v }));
  const setShowArchived = (v: boolean) => setPrefs(p => ({ ...p, showArchived: v }));

  const [showCreate, setShowCreate] = useState(false);
  const selectedProjectId = searchParams.get('id');

  // Fetch projects
  const {
    data: projectsData,
    isLoading: projectsLoading,
    error: projectsError,
  } = useProjects({ includeArchived: showArchived }, initialProjects);
  const { data: projectSummariesData, isLoading: projectSummariesLoading } =
    useProjectSummaries(initialProjectSummaries);

  const { data: selectedProjectTasksData, isLoading: selectedProjectTasksLoading } = useTasks(
    selectedProjectId ? { project: selectedProjectId } : undefined,
    { enabled: Boolean(selectedProjectId) }
  );

  const projects = projectsData?.entities ?? [];
  const selectedProjectTasks = selectedProjectTasksData?.entities ?? [];

  const projectStatsMap = useMemo(() => {
    const summaries = new Map(
      (projectSummariesData?.projects_summary ?? []).map(summary => [summary.id, summary])
    );
    const map = new Map<string, ProjectStats>();
    for (const project of projects) {
      map.set(project.id, projectStatsFromSummary(summaries.get(project.id)));
    }
    return map;
  }, [projects, projectSummariesData?.projects_summary]);

  // Sort projects based on selected sort option
  const sortedProjects = useMemo(() => {
    const sorted = [...projects];
    sorted.sort((a, b) => {
      const statsA = projectStatsMap.get(a.id);
      const statsB = projectStatsMap.get(b.id);

      // Helper for secondary sort: by total tasks, then name
      const secondarySort = () => {
        const totalDiff = (statsB?.total ?? 0) - (statsA?.total ?? 0);
        return totalDiff !== 0 ? totalDiff : a.name.localeCompare(b.name);
      };

      switch (sortBy) {
        case 'active': {
          // Most active = doing + blocked + review
          const activeA = (statsA?.doing ?? 0) + (statsA?.blocked ?? 0) + (statsA?.review ?? 0);
          const activeB = (statsB?.doing ?? 0) + (statsB?.blocked ?? 0) + (statsB?.review ?? 0);
          return activeB !== activeA ? activeB - activeA : secondarySort();
        }
        case 'urgent': {
          // Urgent first = critical + high + overdue
          const urgentA = (statsA?.critical ?? 0) + (statsA?.high ?? 0) + (statsA?.overdue ?? 0);
          const urgentB = (statsB?.critical ?? 0) + (statsB?.high ?? 0) + (statsB?.overdue ?? 0);
          return urgentB !== urgentA ? urgentB - urgentA : secondarySort();
        }
        case 'tasks':
          return (statsB?.total ?? 0) - (statsA?.total ?? 0) || a.name.localeCompare(b.name);
        case 'completion': {
          const completionA = statsA?.total ? (statsA.done / statsA.total) * 100 : 0;
          const completionB = statsB?.total ? (statsB.done / statsB.total) * 100 : 0;
          return completionB !== completionA ? completionB - completionA : secondarySort();
        }
        case 'name':
          return a.name.localeCompare(b.name);
        default:
          return 0;
      }
    });
    return sorted;
  }, [projects, projectStatsMap, sortBy]);

  const selectedProject = sortedProjects.find(p => p.id === selectedProjectId);
  const selectedStats = selectedProjectId ? projectStatsMap.get(selectedProjectId) : null;

  const handleSelectProject = useCallback(
    (projectId: string) => {
      const params = new URLSearchParams(searchParams);
      params.set('id', projectId);
      router.push(`/projects?${params.toString()}`);
    },
    [router, searchParams]
  );

  // Push breadcrumb items when viewing a specific project; otherwise let
  // the layout breadcrumb auto-derive the trail.
  useSetBreadcrumb(
    selectedProject
      ? [
          { label: ROUTE_CONFIG[''].label, href: '/', icon: ROUTE_CONFIG[''].icon },
          { label: 'Projects', href: '/projects', icon: ROUTE_CONFIG.projects.icon },
          { label: selectedProject.name },
        ]
      : null
  );

  const isLoading = projectsLoading || projectSummariesLoading;
  const detailLoading = Boolean(selectedProjectId) && selectedProjectTasksLoading;

  // Calculate total stats across all projects (must be before early returns)
  const totalStats = useMemo(() => {
    const stats = { tasks: 0, active: 0, urgent: 0 };
    for (const s of projectStatsMap.values()) {
      stats.tasks += s.total;
      stats.active += s.doing + s.review;
      stats.urgent += s.critical + s.high;
    }
    return stats;
  }, [projectStatsMap]);

  if (projectsError) {
    return (
      <div className="space-y-4">
        <PageHeader description="Manage your development projects" />
        <ErrorState
          title="Failed to load projects"
          message={projectsError instanceof Error ? projectsError.message : 'Unknown error'}
        />
      </div>
    );
  }

  // Empty state when no projects exist
  if (!isLoading && projects.length === 0) {
    return (
      <div className="space-y-4">
        <PageHeader description="Manage your development projects" meta="0 projects" />
        <ProjectsEmptyState onCreateProject={() => setShowCreate(true)} />
        <CreateProjectDialog
          isOpen={showCreate}
          onClose={() => setShowCreate(false)}
          onCreated={id => router.push(`/projects?id=${id}`)}
        />
      </div>
    );
  }

  return (
    <div className="space-y-4 animate-fade-in">
      <PageHeader
        description="Manage your development projects"
        meta={`${projects.length} projects | ${totalStats.tasks} tasks | ${totalStats.active} active`}
        action={
          <button
            type="button"
            onClick={() => setShowCreate(true)}
            className="shrink-0 px-4 py-2 bg-sc-purple hover:bg-sc-purple/80 text-white rounded-lg font-medium transition-colors flex items-center gap-1.5 text-sm"
          >
            <span>+</span>
            <span>New Project</span>
          </button>
        }
      />

      <CreateProjectDialog
        isOpen={showCreate}
        onClose={() => setShowCreate(false)}
        onCreated={id => router.push(`/projects?id=${id}`)}
      />

      <div className="flex gap-6">
        {/* Sidebar - Project List */}
        <div className="w-80 shrink-0">
          <div className="sticky top-4 space-y-2">
            {/* Header with sort options */}
            <div className="flex items-center justify-between px-1 mb-3">
              <h2 className="text-sm font-semibold text-sc-fg-muted">All Projects</h2>
              {/* Sort + filter options */}
              <div className="flex items-center gap-2">
                {/* Archive toggle */}
                <Tooltip content={showArchived ? 'Hide archived' : 'Show archived'} side="bottom">
                  <button
                    type="button"
                    onClick={() => setShowArchived(!showArchived)}
                    className={`p-1.5 rounded transition-colors ${
                      showArchived
                        ? 'bg-sc-yellow/20 text-sc-yellow'
                        : 'text-sc-fg-subtle hover:text-sc-fg-muted hover:bg-sc-bg-highlight/50'
                    }`}
                  >
                    <Archive width={14} height={14} />
                  </button>
                </Tooltip>
                <span className="w-px h-4 bg-sc-fg-subtle/20" />
                {/* Sort options */}
                {PROJECT_SORT_OPTIONS.map(option => (
                  <Tooltip key={option.value} content={option.label} side="bottom">
                    <button
                      type="button"
                      onClick={() => setSortBy(option.value)}
                      className={`p-1.5 rounded transition-colors ${
                        sortBy === option.value
                          ? 'bg-sc-purple/20 text-sc-purple'
                          : 'text-sc-fg-subtle hover:text-sc-fg-muted hover:bg-sc-bg-highlight/50'
                      }`}
                    >
                      {option.icon}
                    </button>
                  </Tooltip>
                ))}
              </div>
            </div>

            {isLoading ? (
              <div className="space-y-2">
                <ProjectCardSkeleton />
                <ProjectCardSkeleton />
                <ProjectCardSkeleton />
              </div>
            ) : (
              <div className="space-y-2">
                <AnimatePresence mode="popLayout">
                  {sortedProjects.map((project, index) => {
                    const stats = projectStatsMap.get(project.id);
                    return (
                      <motion.div
                        key={project.id}
                        layout
                        initial={{ opacity: 0, x: -20 }}
                        animate={{ opacity: 1, x: 0 }}
                        exit={{ opacity: 0, x: -20 }}
                        transition={{
                          layout: { type: 'spring', stiffness: 350, damping: 30 },
                          opacity: { duration: 0.2, delay: index * 0.03 },
                          x: { duration: 0.2, delay: index * 0.03 },
                        }}
                      >
                        <ProjectCard
                          project={project}
                          stats={stats}
                          isSelected={project.id === selectedProjectId}
                          onClick={() => handleSelectProject(project.id)}
                        />
                      </motion.div>
                    );
                  })}
                </AnimatePresence>
              </div>
            )}
          </div>
        </div>

        {/* Main Content - Project Detail */}
        <div className="flex-1 min-w-0">
          {isLoading || detailLoading ? (
            <ProjectDetailSkeleton />
          ) : !selectedProject ? (
            <div className="flex items-center justify-center h-64 text-sc-fg-subtle">
              <div className="text-center">
                <div className="text-4xl mb-4">◇</div>
                <p>Select a project from the sidebar</p>
              </div>
            </div>
          ) : (
            <ProjectDetail
              project={selectedProject}
              stats={selectedStats}
              tasks={selectedProjectTasks}
            />
          )}
        </div>
      </div>
    </div>
  );
}

// =============================================================================
// ProjectCard Component
// =============================================================================

interface ProjectCardProps {
  project: TaskSummary;
  stats?: ProjectStats;
  isSelected?: boolean;
  onClick?: () => void;
}

function ProjectCard({ project, stats, isSelected, onClick }: ProjectCardProps) {
  const progress = stats && stats.total > 0 ? Math.round((stats.done / stats.total) * 100) : 0;
  const hasActive = stats && stats.doing > 0;
  const isArchived = project.metadata.status === 'archived';

  return (
    <button
      type="button"
      onClick={onClick}
      className={`
        w-full text-left p-4 rounded-xl transition-all duration-150
        border group relative overflow-hidden
        ${
          isArchived
            ? 'bg-sc-bg-base/50 border-sc-fg-subtle/10 opacity-75'
            : isSelected
              ? 'bg-gradient-to-br from-sc-purple/15 via-sc-bg-base to-sc-bg-base border-sc-purple/50 shadow-glow-purple'
              : 'bg-sc-bg-base border-sc-fg-subtle/30 shadow-card hover:border-sc-purple/30 hover:shadow-card-hover hover:bg-sc-bg-highlight/30'
        }
      `}
    >
      {/* Active indicator bar */}
      {hasActive && !isSelected && !isArchived && (
        <div className="absolute left-0 top-0 bottom-0 w-1 bg-sc-purple" />
      )}
      {/* Archived indicator bar */}
      {isArchived && <div className="absolute left-0 top-0 bottom-0 w-1 bg-sc-yellow/50" />}

      {/* Header with name and badges */}
      <div className="flex items-start justify-between gap-2 mb-2">
        <h3
          className={`font-semibold truncate ${
            isArchived
              ? 'text-sc-fg-muted'
              : isSelected
                ? 'text-sc-purple'
                : 'text-sc-fg-primary group-hover:text-white'
          }`}
        >
          {project.name}
        </h3>

        {/* Status badges */}
        <div className="flex items-center gap-1 shrink-0">
          {isArchived && (
            <span className="flex items-center gap-0.5 text-[10px] px-1.5 py-0.5 rounded bg-sc-yellow/20 text-sc-yellow">
              <Archive width={10} height={10} />
            </span>
          )}
          {!isArchived && (stats?.blocked ?? 0) > 0 && (
            <span className="flex items-center gap-0.5 text-[10px] px-1.5 py-0.5 rounded bg-sc-yellow/20 text-sc-yellow">
              <Pause width={10} height={10} />
              {stats?.blocked}
            </span>
          )}
          {!isArchived && (stats?.critical ?? 0) > 0 && (
            <span className="flex items-center gap-0.5 text-[10px] px-1.5 py-0.5 rounded bg-sc-red/20 text-sc-red">
              <Zap width={10} height={10} />
              {stats?.critical}
            </span>
          )}
        </div>
      </div>

      {/* Description */}
      {project.description && (
        <p className="text-xs text-sc-fg-muted line-clamp-2 mb-3">{project.description}</p>
      )}

      {/* Progress section */}
      {stats && stats.total > 0 && (
        <div className="space-y-2">
          {/* Progress bar */}
          <div className="h-1.5 bg-sc-bg-elevated rounded-full overflow-hidden">
            <div
              className={`h-full transition-all duration-500 ${
                progress === 100 ? 'bg-sc-green' : 'bg-sc-purple'
              }`}
              style={{ width: `${progress}%` }}
            />
          </div>

          {/* Stats row */}
          <div className="flex items-center justify-between text-[10px]">
            <div className="flex items-center gap-2 text-sc-fg-subtle">
              <span className="flex items-center gap-1">
                <CheckCircle2 width={10} height={10} className="text-sc-green" />
                {stats.done}/{stats.total}
              </span>
              {stats.doing > 0 && (
                <span className="flex items-center gap-1 text-sc-purple">
                  <Clock width={10} height={10} />
                  {stats.doing} active
                </span>
              )}
            </div>
            <span
              className={`font-medium ${progress === 100 ? 'text-sc-green' : 'text-sc-fg-muted'}`}
            >
              {progress}%
            </span>
          </div>
        </div>
      )}

      {/* Empty project indicator */}
      {(!stats || stats.total === 0) && (
        <div className="text-xs text-sc-fg-subtle italic">No tasks yet</div>
      )}
    </button>
  );
}

function ProjectCardSkeleton() {
  return (
    <div className="p-4 rounded-xl bg-sc-bg-base border border-sc-fg-subtle/30 shadow-card animate-pulse">
      <div className="h-5 w-3/4 bg-sc-bg-elevated rounded mb-2" />
      <div className="h-3 w-full bg-sc-bg-elevated rounded mb-3" />
      <div className="h-1.5 w-full bg-sc-bg-elevated rounded mb-2" />
      <div className="flex justify-between">
        <div className="h-3 w-16 bg-sc-bg-elevated rounded" />
        <div className="h-3 w-8 bg-sc-bg-elevated rounded" />
      </div>
    </div>
  );
}

// =============================================================================
// ProjectDetail Component
// =============================================================================

interface ProjectDetailProps {
  project: TaskSummary;
  stats?: ProjectStats | null;
  tasks: TaskSummary[];
  onDeleted?: () => void;
}

function ProjectDetail({ project, stats, tasks, onDeleted }: ProjectDetailProps) {
  const router = useRouter();
  const updateEntity = useUpdateEntity();
  const deleteEntity = useDeleteEntity();
  const { data: projectMetrics } = useProjectMetrics(project.id);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const progress = stats && stats.total > 0 ? Math.round((stats.done / stats.total) * 100) : 0;

  // Get tech stack from metadata
  const techStack =
    (project.metadata.technologies as string[]) ?? (project.metadata.tech_stack as string[]) ?? [];
  const repoUrl = project.metadata.repository_url as string | undefined;
  const features = (project.metadata.features as string[]) ?? [];

  // Update handlers
  const handleNameSave = useCallback(
    async (value: string) => {
      try {
        await updateEntity.mutateAsync({ id: project.id, updates: { name: value } });
        toast.success('Project name updated');
      } catch {
        toast.error('Failed to update project name');
        throw new Error('Update failed');
      }
    },
    [project.id, updateEntity]
  );

  const handleDescriptionSave = useCallback(
    async (value: string) => {
      try {
        await updateEntity.mutateAsync({ id: project.id, updates: { description: value } });
        toast.success('Description updated');
      } catch {
        toast.error('Failed to update description');
        throw new Error('Update failed');
      }
    },
    [project.id, updateEntity]
  );

  const handleTechStackSave = useCallback(
    async (values: string[]) => {
      try {
        await updateEntity.mutateAsync({
          id: project.id,
          updates: { metadata: { ...project.metadata, technologies: values } },
        });
        toast.success('Tech stack updated');
      } catch {
        toast.error('Failed to update tech stack');
        throw new Error('Update failed');
      }
    },
    [project.id, project.metadata, updateEntity]
  );

  const handleFeaturesSave = useCallback(
    async (values: string[]) => {
      try {
        await updateEntity.mutateAsync({
          id: project.id,
          updates: { metadata: { ...project.metadata, features: values } },
        });
        toast.success('Features updated');
      } catch {
        toast.error('Failed to update features');
        throw new Error('Update failed');
      }
    },
    [project.id, project.metadata, updateEntity]
  );

  const handleRepoSave = useCallback(
    async (value: string) => {
      try {
        await updateEntity.mutateAsync({
          id: project.id,
          updates: { metadata: { ...project.metadata, repository_url: value || undefined } },
        });
        toast.success('Repository URL updated');
      } catch {
        toast.error('Failed to update repository URL');
        throw new Error('Update failed');
      }
    },
    [project.id, project.metadata, updateEntity]
  );

  const handleDelete = useCallback(async () => {
    try {
      await deleteEntity.mutateAsync(project.id);
      toast.success('Project deleted');
      setShowDeleteConfirm(false);
      onDeleted?.();
      router.push('/projects');
    } catch {
      toast.error('Failed to delete project');
    }
  }, [project.id, deleteEntity, onDeleted, router]);

  const isArchived = project.metadata.status === 'archived';

  const handleArchiveToggle = useCallback(async () => {
    const newStatus = isArchived ? 'active' : 'archived';
    try {
      await updateEntity.mutateAsync({
        id: project.id,
        updates: { metadata: { ...project.metadata, status: newStatus } },
      });
      toast.success(isArchived ? 'Project restored' : 'Project archived');
    } catch {
      toast.error('Failed to update project status');
    }
  }, [project.id, project.metadata, updateEntity, isArchived]);

  // Sort tasks: blocked first, then doing, then by priority
  const priorityOrder: Record<string, number> = {
    critical: 0,
    high: 1,
    medium: 2,
    low: 3,
    someday: 4,
  };

  const activeTasks = tasks
    .filter(t => ['doing', 'blocked', 'review'].includes(t.metadata.status as string))
    .sort((a, b) => {
      // Blocked first
      if (a.metadata.status === 'blocked' && b.metadata.status !== 'blocked') return -1;
      if (b.metadata.status === 'blocked' && a.metadata.status !== 'blocked') return 1;
      // Then by priority
      const aPri = priorityOrder[a.metadata.priority as string] ?? 2;
      const bPri = priorityOrder[b.metadata.priority as string] ?? 2;
      return aPri - bPri;
    });

  const upcomingTasks = tasks
    .filter(t => ['todo', 'backlog'].includes(t.metadata.status as string))
    .sort((a, b) => {
      const aPri = priorityOrder[a.metadata.priority as string] ?? 2;
      const bPri = priorityOrder[b.metadata.priority as string] ?? 2;
      return aPri - bPri;
    })
    .slice(0, 5);

  return (
    <div className="space-y-6">
      {/* Header with Inline Editing */}
      <div className="flex items-start justify-between gap-4">
        <div className="flex-1 min-w-0">
          <div className="group/name">
            <EditableText
              value={project.name}
              onSave={handleNameSave}
              placeholder="Project name"
              required
              className="text-2xl font-bold text-sc-fg-primary"
            />
          </div>
          <div className="mt-2 group/desc">
            <EditableText
              value={project.description ?? ''}
              onSave={handleDescriptionSave}
              placeholder="Add a description..."
              multiline
              rows={2}
              className="text-sc-fg-muted"
            />
          </div>
        </div>

        {/* Quick Actions */}
        <div className="flex items-center gap-2 shrink-0">
          {repoUrl && (
            <a
              href={repoUrl}
              target="_blank"
              rel="noopener noreferrer"
              className="p-2 bg-sc-bg-elevated hover:bg-sc-bg-highlight border border-sc-fg-subtle/20 rounded-lg text-sc-fg-muted hover:text-sc-cyan transition-colors"
              title="View Repository"
            >
              <GitBranch width={18} height={18} />
            </a>
          )}
          <Link
            href={`/tasks?project=${project.id}`}
            className="px-3 py-2 bg-sc-bg-elevated hover:bg-sc-bg-highlight border border-sc-fg-subtle/20 rounded-lg text-sc-fg-muted hover:text-sc-cyan transition-colors flex items-center gap-1.5 text-sm"
          >
            <FolderKanban width={14} height={14} />
            <span>Tasks</span>
          </Link>
          <Tooltip content={isArchived ? 'Restore project' : 'Archive project'} side="bottom">
            <button
              type="button"
              onClick={handleArchiveToggle}
              className={`p-2 bg-sc-bg-elevated border border-sc-fg-subtle/20 rounded-lg transition-colors ${
                isArchived
                  ? 'hover:bg-sc-green/20 hover:border-sc-green/30 text-sc-yellow hover:text-sc-green'
                  : 'hover:bg-sc-yellow/20 hover:border-sc-yellow/30 text-sc-fg-muted hover:text-sc-yellow'
              }`}
            >
              <Archive width={18} height={18} />
            </button>
          </Tooltip>
          <button
            type="button"
            onClick={() => setShowDeleteConfirm(true)}
            className="p-2 bg-sc-bg-elevated hover:bg-sc-red/20 border border-sc-fg-subtle/20 hover:border-sc-red/30 rounded-lg text-sc-fg-muted hover:text-sc-red transition-colors"
            title="Delete Project"
          >
            <Trash width={18} height={18} />
          </button>
        </div>
      </div>

      {/* Delete Confirmation Modal */}
      {showDeleteConfirm && (
        <div className="fixed inset-0 z-50 flex items-center justify-center">
          <button
            type="button"
            className="absolute inset-0 bg-sc-bg-dark/80 backdrop-blur-sm cursor-default"
            onClick={() => setShowDeleteConfirm(false)}
            aria-label="Close"
          />
          <div className="relative bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-6 max-w-md w-full mx-4 shadow-2xl">
            <div className="flex items-start gap-4">
              <div className="p-3 bg-sc-red/20 rounded-full">
                <AlertTriangle width={24} height={24} className="text-sc-red" />
              </div>
              <div className="flex-1">
                <h3 className="text-lg font-semibold text-sc-fg-primary mb-2">Delete Project?</h3>
                <p className="text-sm text-sc-fg-muted mb-1">
                  Are you sure you want to delete <strong>{project.name}</strong>?
                </p>
                {stats && stats.total > 0 && (
                  <p className="text-sm text-sc-yellow">
                    This project has {stats.total} task{stats.total !== 1 ? 's' : ''} that will be
                    orphaned.
                  </p>
                )}
              </div>
            </div>
            <div className="flex justify-end gap-3 mt-6">
              <button
                type="button"
                onClick={() => setShowDeleteConfirm(false)}
                className="px-4 py-2 text-sc-fg-muted hover:text-sc-fg-primary transition-colors"
              >
                Cancel
              </button>
              <button
                type="button"
                onClick={handleDelete}
                disabled={deleteEntity.isPending}
                className="px-4 py-2 bg-sc-red hover:bg-sc-red/80 disabled:opacity-50 text-white rounded-lg font-medium transition-colors"
              >
                {deleteEntity.isPending ? 'Deleting...' : 'Delete Project'}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Stats Overview */}
      <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
        {/* Progress Card */}
        <div className="col-span-2 bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
          <div className="flex items-center justify-between mb-3">
            <h2 className="font-semibold text-sc-fg-primary">Progress</h2>
            <span
              className={`text-2xl font-bold ${progress === 100 ? 'text-sc-green' : 'text-sc-purple'}`}
            >
              {progress}%
            </span>
          </div>
          <div className="h-3 bg-sc-bg-elevated rounded-full overflow-hidden mb-2">
            <div
              className={`h-full transition-all duration-500 ${
                progress === 100 ? 'bg-sc-green' : 'bg-sc-purple'
              }`}
              style={{ width: `${progress}%` }}
            />
          </div>
          <div className="flex justify-between text-sm text-sc-fg-muted">
            <span>{stats?.done ?? 0} completed</span>
            <span>{stats?.total ?? 0} total</span>
          </div>
        </div>

        {/* Active Work */}
        <div className="bg-sc-bg-base border border-sc-purple/30 rounded-xl p-5 shadow-card">
          <div className="flex items-center gap-2 text-sc-purple mb-1">
            <Clock width={16} height={16} />
            <span className="text-sm font-medium">Active</span>
          </div>
          <div className="text-3xl font-bold text-sc-fg-primary">{stats?.doing ?? 0}</div>
          <div className="text-xs text-sc-fg-subtle mt-1">{stats?.review ?? 0} in review</div>
        </div>

        {/* Blocked/Urgent */}
        <div
          className={`bg-sc-bg-base border rounded-xl p-5 shadow-card ${
            (stats?.blocked ?? 0) > 0 || (stats?.critical ?? 0) > 0
              ? 'border-sc-red/30'
              : 'border-sc-fg-subtle/30'
          }`}
        >
          <div
            className={`flex items-center gap-2 mb-1 ${
              (stats?.blocked ?? 0) > 0 ? 'text-sc-yellow' : 'text-sc-coral'
            }`}
          >
            {(stats?.blocked ?? 0) > 0 ? (
              <Pause width={16} height={16} />
            ) : (
              <AlertTriangle width={16} height={16} />
            )}
            <span className="text-sm font-medium">
              {(stats?.blocked ?? 0) > 0 ? 'Blocked' : 'Urgent'}
            </span>
          </div>
          <div className="text-3xl font-bold text-sc-fg-primary">
            {(stats?.blocked ?? 0) > 0
              ? stats?.blocked
              : (stats?.critical ?? 0) + (stats?.high ?? 0)}
          </div>
          <div className="text-xs text-sc-fg-subtle mt-1">
            {(stats?.blocked ?? 0) > 0 ? 'needs attention' : 'high priority'}
          </div>
        </div>
      </div>

      {/* Velocity Chart - Show if we have trend data */}
      {projectMetrics?.metrics?.velocity_trend &&
        projectMetrics.metrics.velocity_trend.length > 0 && (
          <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
            <div className="flex items-center justify-between mb-4">
              <div className="flex items-center gap-2">
                <TrendingUp width={16} height={16} className="text-sc-green" />
                <h2 className="font-semibold text-sc-fg-primary">Completion Velocity</h2>
              </div>
              <div className="flex items-center gap-4 text-sm">
                <span className="text-sc-fg-muted">
                  <span className="text-sc-fg-primary font-medium">
                    {projectMetrics.metrics.tasks_completed_last_7d}
                  </span>{' '}
                  completed this week
                </span>
              </div>
            </div>
            <VelocityLineChart data={projectMetrics.metrics.velocity_trend} />
          </div>
        )}

      {/* Active Work Section */}
      {activeTasks.length > 0 && (
        <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
          <div className="flex items-center justify-between mb-4">
            <h2 className="font-semibold text-sc-fg-primary">Active Work</h2>
            <span className="text-xs text-sc-fg-subtle">{activeTasks.length} tasks</span>
          </div>
          <div className="space-y-2">
            {activeTasks.slice(0, 5).map(task => (
              <TaskRow key={task.id} task={task} />
            ))}
            {activeTasks.length > 5 && (
              <Link
                href={`/tasks?project=${project.id}`}
                className="block text-center text-sm text-sc-purple hover:text-sc-purple/80 py-2"
              >
                View all {activeTasks.length} active tasks →
              </Link>
            )}
          </div>
        </div>
      )}

      {/* Up Next Section */}
      {upcomingTasks.length > 0 && (
        <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
          <div className="flex items-center justify-between mb-4">
            <h2 className="font-semibold text-sc-fg-primary">Up Next</h2>
            <span className="text-xs text-sc-fg-subtle">
              {stats?.todo ?? 0} todo, {stats?.backlog ?? 0} backlog
            </span>
          </div>
          <div className="space-y-2">
            {upcomingTasks.map(task => (
              <TaskRow key={task.id} task={task} />
            ))}
          </div>
        </div>
      )}

      {/* Tech & Features Grid - Always show for editing */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
          <h2 className="font-semibold text-sc-fg-primary mb-3">Tech Stack</h2>
          <EditableTags
            values={techStack}
            onSave={handleTechStackSave}
            placeholder="Add technology..."
            addPlaceholder="e.g., React, Python"
            tagClassName="bg-sc-cyan/10 text-sc-cyan border-sc-cyan/20"
          />
        </div>

        <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
          <h2 className="font-semibold text-sc-fg-primary mb-3">Features</h2>
          <EditableTags
            values={features}
            onSave={handleFeaturesSave}
            placeholder="Add feature..."
            addPlaceholder="e.g., Auth, API"
            tagClassName="bg-sc-purple/10 text-sc-purple border-sc-purple/20"
          />
        </div>
      </div>

      {/* Repository URL */}
      <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
        <h2 className="font-semibold text-sc-fg-primary mb-3 flex items-center gap-2">
          <GitBranch width={16} height={16} className="text-sc-coral" />
          Repository
        </h2>
        <EditableText
          value={repoUrl ?? ''}
          onSave={handleRepoSave}
          placeholder="Add repository URL..."
          className="text-sm text-sc-cyan"
        />
      </div>

      {/* Team Members */}
      <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
        <h2 className="font-semibold text-sc-fg-primary mb-3 flex items-center gap-2">
          <Users width={16} height={16} className="text-sc-purple" />
          Team
        </h2>
        <ProjectMembersList projectId={project.id} />
      </div>

      {/* Empty state for no tasks */}
      {(!stats || stats.total === 0) && (
        <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-8 text-center shadow-card">
          <div className="mb-4 flex justify-center">
            <FolderKanban width={40} height={40} className="text-sc-yellow" />
          </div>
          <h3 className="text-lg font-semibold text-sc-fg-primary mb-2">No tasks yet</h3>
          <p className="text-sc-fg-muted mb-4">Create your first task to get started</p>
          <Link
            href={`/tasks?project=${project.id}`}
            className="inline-flex items-center gap-2 px-4 py-2 bg-sc-purple hover:bg-sc-purple/80 text-white rounded-lg font-medium transition-colors"
          >
            <Plus width={16} height={16} />
            <span>Add Task</span>
          </Link>
        </div>
      )}
    </div>
  );
}

// Task row component for lists
function TaskRow({ task }: { task: TaskSummary }) {
  const status = (task.metadata.status ?? 'todo') as TaskStatus;
  const priority = task.metadata.priority as string | undefined;
  const config = TASK_STATUS_CONFIG[status as keyof typeof TASK_STATUS_CONFIG];

  const priorityColors: Record<string, string> = {
    critical: 'text-sc-red',
    high: 'text-sc-coral',
    medium: 'text-sc-purple',
    low: 'text-sc-cyan',
    someday: 'text-sc-fg-subtle',
  };

  return (
    <Link
      href={`/tasks/${task.id}`}
      className="flex items-center gap-3 p-3 rounded-lg bg-sc-bg-highlight/30 hover:bg-sc-bg-highlight/50 transition-colors group"
    >
      <span className={config?.textClass}>{config?.icon}</span>
      <span className="flex-1 text-sm text-sc-fg-primary group-hover:text-white truncate">
        {task.name}
      </span>
      {priority && (
        <span className={`text-xs ${priorityColors[priority] ?? 'text-sc-fg-muted'}`}>
          {priority}
        </span>
      )}
      <span className={`text-xs px-2 py-0.5 rounded ${config?.bgClass} ${config?.textClass}`}>
        {config?.label}
      </span>
    </Link>
  );
}

function ProjectDetailSkeleton() {
  return (
    <div className="space-y-6 animate-pulse">
      <div>
        <div className="h-8 w-1/3 bg-sc-bg-elevated rounded" />
        <div className="h-4 w-2/3 bg-sc-bg-elevated rounded mt-3" />
      </div>
      <div className="grid grid-cols-4 gap-4">
        <div className="col-span-2 bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
          <div className="h-4 w-20 bg-sc-bg-elevated rounded mb-3" />
          <div className="h-3 w-full bg-sc-bg-elevated rounded" />
        </div>
        <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
          <div className="h-4 w-16 bg-sc-bg-elevated rounded mb-2" />
          <div className="h-8 w-12 bg-sc-bg-elevated rounded" />
        </div>
        <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
          <div className="h-4 w-16 bg-sc-bg-elevated rounded mb-2" />
          <div className="h-8 w-12 bg-sc-bg-elevated rounded" />
        </div>
      </div>
      <div className="bg-sc-bg-base border border-sc-fg-subtle/30 rounded-xl p-5 shadow-card">
        <div className="h-4 w-24 bg-sc-bg-elevated rounded mb-4" />
        <div className="space-y-2">
          <div className="h-12 w-full bg-sc-bg-elevated rounded" />
          <div className="h-12 w-full bg-sc-bg-elevated rounded" />
        </div>
      </div>
    </div>
  );
}

// =============================================================================
// ProjectMembersList Component
// =============================================================================

const PROJECT_ROLES: ProjectRole[] = [
  'project_owner',
  'project_maintainer',
  'project_contributor',
  'project_viewer',
];

const ROLE_DISPLAY: Record<ProjectRole, string> = {
  project_owner: 'Owner',
  project_maintainer: 'Maintainer',
  project_contributor: 'Contributor',
  project_viewer: 'Viewer',
};

function ProjectMembersList({ projectId }: { projectId: string }) {
  const { data: me } = useMe();
  const { data, isLoading } = useProjectMembers(projectId);
  const updateRole = useUpdateProjectMemberRole();
  const removeMember = useRemoveProjectMember();

  const currentUserId = me?.user?.id;

  if (isLoading) {
    return (
      <div className="flex items-center justify-center p-4">
        <Spinner size="sm" />
      </div>
    );
  }

  if (!data?.members.length) {
    return <p className="text-sc-fg-muted text-sm">No team members yet.</p>;
  }

  const canManage = data.can_manage;

  const handleRoleChange = async (userId: string, newRole: ProjectRole) => {
    try {
      await updateRole.mutateAsync({ projectId, userId, role: newRole });
      toast.success('Role updated');
    } catch {
      toast.error('Failed to update role');
    }
  };

  const handleRemove = async (userId: string, userName: string | null) => {
    if (!confirm(`Remove ${userName || 'this member'} from the project?`)) return;
    try {
      await removeMember.mutateAsync({ projectId, userId });
      toast.success('Member removed');
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to remove member');
    }
  };

  return (
    <div className="divide-y divide-sc-fg-subtle/10">
      {data.members.map(member => (
        <div key={member.user.id} className="flex items-center gap-3 py-3 px-1">
          {member.user.avatar_url ? (
            <img
              src={member.user.avatar_url}
              alt=""
              className="w-8 h-8 rounded-full border border-sc-fg-subtle/20"
            />
          ) : (
            <div className="w-8 h-8 rounded-full bg-sc-bg-highlight flex items-center justify-center">
              <User width={14} height={14} className="text-sc-fg-muted" />
            </div>
          )}
          <div className="flex-1 min-w-0">
            <p className="text-sm font-medium text-sc-fg-primary truncate">
              {member.user.name || member.user.email || 'Unknown'}
              {member.user.id === currentUserId && (
                <span className="ml-2 text-xs text-sc-purple">(you)</span>
              )}
              {member.is_owner && <span className="ml-2 text-xs text-sc-yellow">(owner)</span>}
            </p>
            <p className="text-xs text-sc-fg-muted truncate">{member.user.email}</p>
          </div>
          {canManage && !member.is_owner && member.user.id !== currentUserId ? (
            <div className="flex items-center gap-2">
              <select
                value={member.role}
                onChange={e => handleRoleChange(member.user.id, e.target.value as ProjectRole)}
                className="text-xs bg-sc-bg-highlight border border-sc-fg-subtle/20 rounded px-2 py-1 text-sc-fg-secondary"
              >
                {PROJECT_ROLES.filter(role => role !== 'project_owner').map(role => (
                  <option key={role} value={role}>
                    {ROLE_DISPLAY[role]}
                  </option>
                ))}
              </select>
              <button
                type="button"
                onClick={() => handleRemove(member.user.id, member.user.name)}
                className="p-1 text-sc-fg-muted hover:text-sc-red transition-colors"
                title="Remove member"
              >
                <Trash width={14} height={14} />
              </button>
            </div>
          ) : (
            <span className="text-xs text-sc-fg-muted px-2 py-1 bg-sc-bg-highlight rounded">
              {ROLE_DISPLAY[member.role]}
            </span>
          )}
        </div>
      ))}
    </div>
  );
}
