/**
 * Dashboard Data Hook
 *
 * Provides data for the main dashboard including:
 * - Quick stats (projects, agents, issues, approvals)
 * - Recent projects
 * - Pending approvals
 *
 * Fetches real data from the API.
 *
 * @see Issue #53
 */

import { useQuery } from '@tanstack/react-query';
import { listProjects as listProjectsApi } from '@/lib/api/generated';
import type { ProjectResponse } from '@/lib/api/generated';
import type { AutonomyLevel, Project, ProjectStatus } from '@/components/projects/types';

// ============================================================================
// Types
// ============================================================================

export interface DashboardStats {
  activeProjects: number;
  runningAgents: number;
  openIssues: number;
  pendingApprovals: number;
}

export interface DashboardProject extends Project {
  progress: number;
  openIssues: number;
  activeAgents: number;
  currentSprint?: string;
  lastActivity: string;
}

export interface PendingApproval {
  id: string;
  type: 'sprint_boundary' | 'code_review' | 'architecture_decision' | 'deployment';
  title: string;
  description: string;
  projectId: string;
  projectName: string;
  requestedBy: string;
  requestedAt: string;
  priority: 'low' | 'medium' | 'high' | 'critical';
}

export interface DashboardData {
  stats: DashboardStats;
  recentProjects: DashboardProject[];
  pendingApprovals: PendingApproval[];
}

// ============================================================================
// Helpers
// ============================================================================

/**
 * Format a date string as relative time (e.g., "2 minutes ago")
 */
function formatRelativeTime(dateStr: string): string {
  const date = new Date(dateStr);
  const now = new Date();
  const diffMs = now.getTime() - date.getTime();
  const diffMins = Math.floor(diffMs / 60000);
  const diffHours = Math.floor(diffMins / 60);
  const diffDays = Math.floor(diffHours / 24);
  const diffWeeks = Math.floor(diffDays / 7);
  const diffMonths = Math.floor(diffDays / 30);

  if (diffMins < 1) return 'Just now';
  if (diffMins < 60) return `${diffMins} minute${diffMins > 1 ? 's' : ''} ago`;
  if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;
  if (diffDays < 7) return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;
  if (diffWeeks < 4) return `${diffWeeks} week${diffWeeks > 1 ? 's' : ''} ago`;
  return `${diffMonths} month${diffMonths > 1 ? 's' : ''} ago`;
}

/**
 * Maps API ProjectResponse to DashboardProject format
 */
function mapToDashboardProject(
  project: ProjectResponse & Record<string, unknown>
): DashboardProject {
  const updatedAt = project.updated_at || project.created_at || new Date().toISOString();
  const createdAt = project.created_at || new Date().toISOString();

  return {
    id: project.id,
    name: project.name,
    description: project.description || undefined,
    status: project.status as ProjectStatus,
    autonomy_level: (project.autonomy_level || 'milestone') as AutonomyLevel,
    created_at: createdAt,
    updated_at: updatedAt,
    owner_id: project.owner_id || 'unknown',
    progress: (project.progress as number) || 0,
    openIssues: (project.openIssues as number) || project.issue_count || 0,
    activeAgents: (project.activeAgents as number) || project.agent_count || 0,
    currentSprint: project.active_sprint_name || undefined,
    lastActivity: formatRelativeTime(updatedAt),
  };
}

// ============================================================================
// Mock Data (for pending approvals - no backend endpoint yet)
// ============================================================================

const mockApprovals: PendingApproval[] = [
  {
    id: 'approval-001',
    type: 'sprint_boundary',
    title: 'Sprint 1 Completion Review',
    description: 'Review sprint deliverables and approve transition to Sprint 2',
    projectId: 'proj-001',
    projectName: 'E-Commerce Platform Redesign',
    requestedBy: 'Product Owner Agent',
    requestedAt: new Date().toISOString(),
    priority: 'high',
  },
  {
    id: 'approval-002',
    type: 'architecture_decision',
    title: 'Database Migration Strategy',
    description: 'Approve PostgreSQL to CockroachDB migration plan',
    projectId: 'proj-002',
    projectName: 'Mobile Banking App',
    requestedBy: 'Architect Agent',
    requestedAt: new Date(Date.now() - 3600000).toISOString(),
    priority: 'medium',
  },
];

// ============================================================================
// Hook
// ============================================================================

/**
 * Fetches dashboard data (stats, recent projects, pending approvals)
 *
 * @returns Query result with dashboard data
 */
export function useDashboard() {
  return useQuery<DashboardData>({
    queryKey: ['dashboard'],
    queryFn: async () => {
      // Fetch real projects from API
      const response = await listProjectsApi({
        query: {
          limit: 6,
        },
      });

      if (response.error) {
        throw new Error('Failed to fetch dashboard data');
      }

      const projects = response.data.data.map((p) =>
        mapToDashboardProject(p as ProjectResponse & Record<string, unknown>)
      );

      // Sort by updated_at (most recent first)
      projects.sort(
        (a, b) =>
          new Date(b.updated_at || b.created_at).getTime() -
          new Date(a.updated_at || a.created_at).getTime()
      );

      // Calculate stats from real data
      const activeProjects = projects.filter((p) => p.status === 'active').length;
      const runningAgents = projects.reduce((sum, p) => sum + p.activeAgents, 0);
      const openIssues = projects.reduce((sum, p) => sum + p.openIssues, 0);

      return {
        stats: {
          activeProjects,
          runningAgents,
          openIssues,
          pendingApprovals: mockApprovals.length,
        },
        recentProjects: projects,
        pendingApprovals: mockApprovals,
      };
    },
    staleTime: 30000, // 30 seconds
    refetchInterval: 60000, // Refetch every minute
  });
}

/**
 * Fetches only dashboard stats
 */
export function useDashboardStats() {
  return useQuery<DashboardStats>({
    queryKey: ['dashboard', 'stats'],
    queryFn: async () => {
      const response = await listProjectsApi({
        query: { limit: 100 },
      });

      if (response.error) {
        throw new Error('Failed to fetch stats');
      }

      const projects = response.data.data.map((p) =>
        mapToDashboardProject(p as ProjectResponse & Record<string, unknown>)
      );

      return {
        activeProjects: projects.filter((p) => p.status === 'active').length,
        runningAgents: projects.reduce((sum, p) => sum + p.activeAgents, 0),
        openIssues: projects.reduce((sum, p) => sum + p.openIssues, 0),
        pendingApprovals: mockApprovals.length,
      };
    },
    staleTime: 30000,
    refetchInterval: 60000,
  });
}

/**
 * Fetches recent projects for dashboard
 *
 * @param limit - Maximum number of projects to return
 */
export function useRecentProjects(limit: number = 6) {
  return useQuery<DashboardProject[]>({
    queryKey: ['dashboard', 'recentProjects', limit],
    queryFn: async () => {
      const response = await listProjectsApi({
        query: { limit },
      });

      if (response.error) {
        throw new Error('Failed to fetch recent projects');
      }

      const projects = response.data.data.map((p) =>
        mapToDashboardProject(p as ProjectResponse & Record<string, unknown>)
      );

      // Sort by updated_at (most recent first)
      projects.sort(
        (a, b) =>
          new Date(b.updated_at || b.created_at).getTime() -
          new Date(a.updated_at || a.created_at).getTime()
      );

      return projects;
    },
    staleTime: 30000,
  });
}

/**
 * Fetches pending approvals
 */
export function usePendingApprovals() {
  return useQuery<PendingApproval[]>({
    queryKey: ['dashboard', 'pendingApprovals'],
    queryFn: async () => {
      // TODO: Fetch from real API when endpoint exists
      return mockApprovals;
    },
    staleTime: 30000,
  });
}
