/**
 * Project Dashboard Component
 *
 * Main dashboard view for a project showing agents, sprints, issues, and activity.
 * Integrates real-time updates via SSE.
 *
 * @see Issue #40
 */

'use client';

import { useCallback, useMemo, useState } from 'react';
import { useRouter } from 'next/navigation';
import { AlertCircle, RefreshCw } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { ConnectionStatus } from '@/components/events/ConnectionStatus';
import { useProjectEvents } from '@/lib/hooks/useProjectEvents';
import { EventType, type ProjectEvent } from '@/lib/types/events';
import { ProjectHeader } from './ProjectHeader';
import { AgentPanel } from './AgentPanel';
import { SprintProgress } from './SprintProgress';
import { IssueSummary } from './IssueSummary';
import { RecentActivity } from './RecentActivity';
import type {
  Project,
  AgentInstance,
  Sprint,
  BurndownDataPoint,
  IssueCountSummary,
  ActivityItem,
} from './types';

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

interface ProjectDashboardProps {
  /** Project ID */
  projectId: string;
  /** Additional CSS classes */
  className?: string;
}

// ============================================================================
// Mock Data (to be replaced with API calls)
// ============================================================================

// Mock data for development - will be replaced with TanStack Query hooks
const mockProject: Project = {
  id: 'proj-001',
  name: 'E-Commerce Platform Redesign',
  description: 'Complete redesign of the e-commerce platform with modern UI/UX',
  status: 'active',
  autonomy_level: 'milestone',
  current_sprint_id: 'sprint-003',
  created_at: '2025-01-15T00:00:00Z',
  owner_id: 'user-001',
};

const mockAgents: AgentInstance[] = [
  {
    id: 'agent-001',
    agent_type_id: 'type-po',
    project_id: 'proj-001',
    name: 'Product Owner',
    role: 'product_owner',
    status: 'working',
    current_task: 'Reviewing user story acceptance criteria',
    last_activity_at: new Date(Date.now() - 2 * 60 * 1000).toISOString(),
    spawned_at: '2025-01-15T00:00:00Z',
    avatar: 'PO',
  },
  {
    id: 'agent-002',
    agent_type_id: 'type-arch',
    project_id: 'proj-001',
    name: 'Architect',
    role: 'architect',
    status: 'working',
    current_task: 'Designing API contract for checkout flow',
    last_activity_at: new Date(Date.now() - 5 * 60 * 1000).toISOString(),
    spawned_at: '2025-01-15T00:00:00Z',
    avatar: 'AR',
  },
  {
    id: 'agent-003',
    agent_type_id: 'type-be',
    project_id: 'proj-001',
    name: 'Backend Engineer',
    role: 'backend_engineer',
    status: 'idle',
    current_task: 'Waiting for architecture review',
    last_activity_at: new Date(Date.now() - 15 * 60 * 1000).toISOString(),
    spawned_at: '2025-01-15T00:00:00Z',
    avatar: 'BE',
  },
  {
    id: 'agent-004',
    agent_type_id: 'type-fe',
    project_id: 'proj-001',
    name: 'Frontend Engineer',
    role: 'frontend_engineer',
    status: 'working',
    current_task: 'Implementing product catalog component',
    last_activity_at: new Date(Date.now() - 1 * 60 * 1000).toISOString(),
    spawned_at: '2025-01-15T00:00:00Z',
    avatar: 'FE',
  },
  {
    id: 'agent-005',
    agent_type_id: 'type-qa',
    project_id: 'proj-001',
    name: 'QA Engineer',
    role: 'qa_engineer',
    status: 'waiting',
    current_task: 'Preparing test cases for Sprint 3',
    last_activity_at: new Date(Date.now() - 30 * 60 * 1000).toISOString(),
    spawned_at: '2025-01-15T00:00:00Z',
    avatar: 'QA',
  },
];

const mockSprint: Sprint = {
  id: 'sprint-003',
  project_id: 'proj-001',
  name: 'Sprint 3',
  goal: 'Complete checkout flow',
  status: 'active',
  start_date: '2025-01-27',
  end_date: '2025-02-10',
  total_issues: 15,
  completed_issues: 8,
  in_progress_issues: 4,
  blocked_issues: 1,
  todo_issues: 2,
};

const mockBurndownData: BurndownDataPoint[] = [
  { day: 1, remaining: 45, ideal: 45 },
  { day: 2, remaining: 42, ideal: 42 },
  { day: 3, remaining: 38, ideal: 39 },
  { day: 4, remaining: 35, ideal: 36 },
  { day: 5, remaining: 30, ideal: 33 },
  { day: 6, remaining: 28, ideal: 30 },
  { day: 7, remaining: 25, ideal: 27 },
  { day: 8, remaining: 20, ideal: 24 },
];

const mockIssueSummary: IssueCountSummary = {
  open: 12,
  in_progress: 8,
  in_review: 3,
  blocked: 2,
  closed: 45,
  total: 70,
};

const mockActivity: ActivityItem[] = [
  {
    id: 'act-001',
    type: 'agent_message',
    agent: 'Product Owner',
    message: 'Approved user story #42: Cart checkout flow',
    timestamp: new Date(Date.now() - 2 * 60 * 1000).toISOString(),
  },
  {
    id: 'act-002',
    type: 'issue_update',
    agent: 'Backend Engineer',
    message: 'Moved issue #38 to "In Review"',
    timestamp: new Date(Date.now() - 8 * 60 * 1000).toISOString(),
  },
  {
    id: 'act-003',
    type: 'agent_status',
    agent: 'Frontend Engineer',
    message: 'Started working on issue #45',
    timestamp: new Date(Date.now() - 15 * 60 * 1000).toISOString(),
  },
  {
    id: 'act-004',
    type: 'approval_request',
    agent: 'Architect',
    message: 'Requesting approval for API design document',
    timestamp: new Date(Date.now() - 25 * 60 * 1000).toISOString(),
    requires_action: true,
  },
  {
    id: 'act-005',
    type: 'sprint_event',
    agent: 'System',
    message: 'Sprint 3 daily standup completed',
    timestamp: new Date(Date.now() - 60 * 60 * 1000).toISOString(),
  },
];

// ============================================================================
// Helper Functions
// ============================================================================

/**
 * Convert SSE events to activity items
 */
function eventToActivity(event: ProjectEvent): ActivityItem {
  const getAgentName = (event: ProjectEvent): string | undefined => {
    if (event.actor_type === 'agent') {
      const payload = event.payload as Record<string, unknown>;
      return (payload.agent_name as string) || 'Agent';
    }
    if (event.actor_type === 'system') {
      return 'System';
    }
    return undefined;
  };

  const getMessage = (event: ProjectEvent): string => {
    const payload = event.payload as Record<string, unknown>;
    switch (event.type) {
      case EventType.AGENT_SPAWNED:
        return `spawned as ${payload.role || 'agent'}`;
      case EventType.AGENT_MESSAGE:
        return String(payload.message || 'sent a message');
      case EventType.AGENT_STATUS_CHANGED:
        return `status changed to ${payload.new_status}`;
      case EventType.ISSUE_CREATED:
        return `created issue: ${payload.title}`;
      case EventType.ISSUE_UPDATED:
        return `updated issue #${payload.issue_id}`;
      case EventType.APPROVAL_REQUESTED:
        return String(payload.description || 'requested approval');
      case EventType.SPRINT_STARTED:
        return `started sprint: ${payload.sprint_name}`;
      default:
        return event.type.replace(/_/g, ' ');
    }
  };

  const getType = (event: ProjectEvent): ActivityItem['type'] => {
    if (event.type.startsWith('agent.message')) return 'agent_message';
    if (event.type.startsWith('agent.')) return 'agent_status';
    if (event.type.startsWith('issue.')) return 'issue_update';
    if (event.type.startsWith('approval.')) return 'approval_request';
    if (event.type.startsWith('sprint.')) return 'sprint_event';
    return 'system';
  };

  return {
    id: event.id,
    type: getType(event),
    agent: getAgentName(event),
    message: getMessage(event),
    timestamp: event.timestamp,
    requires_action: event.type === EventType.APPROVAL_REQUESTED,
  };
}

// ============================================================================
// Main Component
// ============================================================================

export function ProjectDashboard({ projectId, className }: ProjectDashboardProps) {
  const router = useRouter();
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // SSE connection for real-time updates
  const {
    events: sseEvents,
    connectionState,
    error: sseError,
    retryCount,
    reconnect,
  } = useProjectEvents(projectId, {
    autoConnect: true,
    onEvent: (event) => {
      // Handle specific event types for state updates
      console.log('[Dashboard] Received event:', event.type);
    },
  });

  // Convert SSE events to activity items
  const sseActivities = useMemo(() => {
    return sseEvents.slice(-10).map(eventToActivity);
  }, [sseEvents]);

  // Merge mock activities with SSE activities (SSE takes priority)
  const allActivities = useMemo(() => {
    const merged = [...sseActivities, ...mockActivity];
    // Sort by timestamp, newest first
    merged.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
    return merged.slice(0, 10);
  }, [sseActivities]);

  // Use mock data for now (will be replaced with TanStack Query)
  const project = mockProject;
  const agents = mockAgents;
  const sprint = mockSprint;
  const burndownData = mockBurndownData;
  const issueSummary = mockIssueSummary;

  // Event handlers
  const handleStartSprint = useCallback(() => {
    console.log('Start sprint clicked');
    // TODO: Implement start sprint action
  }, []);

  const handlePauseProject = useCallback(() => {
    console.log('Pause project clicked');
    // TODO: Implement pause project action
  }, []);

  const handleCreateSprint = useCallback(() => {
    console.log('Create sprint clicked');
    // TODO: Navigate to create sprint page
  }, []);

  const handleSettings = useCallback(() => {
    router.push(`/projects/${projectId}/settings`);
  }, [router, projectId]);

  const handleManageAgents = useCallback(() => {
    router.push(`/projects/${projectId}/agents`);
  }, [router, projectId]);

  const handleAgentAction = useCallback(
    (agentId: string, action: 'view' | 'pause' | 'restart' | 'terminate') => {
      console.log(`Agent action: ${action} on ${agentId}`);
      // TODO: Implement agent actions
    },
    []
  );

  const handleViewAllIssues = useCallback(() => {
    router.push(`/projects/${projectId}/issues`);
  }, [router, projectId]);

  const handleViewAllActivity = useCallback(() => {
    router.push(`/projects/${projectId}/activity`);
  }, [router, projectId]);

  const handleActionClick = useCallback((activityId: string) => {
    console.log(`Action clicked for activity: ${activityId}`);
    // TODO: Navigate to approval page
  }, []);

  // Error state
  if (error) {
    return (
      <div className={cn('container mx-auto px-4 py-6', className)}>
        <Alert variant="destructive">
          <AlertCircle className="h-4 w-4" />
          <AlertTitle>Error loading project</AlertTitle>
          <AlertDescription className="flex items-center gap-2">
            {error}
            <Button
              variant="outline"
              size="sm"
              onClick={() => {
                setError(null);
                setIsLoading(true);
                // TODO: Refetch data
              }}
            >
              <RefreshCw className="mr-2 h-4 w-4" />
              Retry
            </Button>
          </AlertDescription>
        </Alert>
      </div>
    );
  }

  return (
    <div className={cn('min-h-screen bg-background', className)} data-testid="project-dashboard">
      <div className="container mx-auto px-4 py-6">
        <div className="space-y-6">
          {/* SSE Connection Status - only show if not connected */}
          {connectionState !== 'connected' && (
            <ConnectionStatus
              state={connectionState}
              error={sseError}
              retryCount={retryCount}
              onReconnect={reconnect}
              compact
              className="mb-4"
            />
          )}

          {/* Header Section */}
          <ProjectHeader
            project={project}
            isLoading={isLoading}
            canPause={project.status === 'active'}
            canStart={true}
            onStartSprint={handleStartSprint}
            onPauseProject={handlePauseProject}
            onCreateSprint={handleCreateSprint}
            onSettings={handleSettings}
          />

          {/* Main Content Grid */}
          <div className="grid gap-6 lg:grid-cols-3">
            {/* Left Column - Agent Panel & Sprint Overview */}
            <div className="space-y-6 lg:col-span-2">
              {/* Agent Panel */}
              <AgentPanel
                agents={agents}
                isLoading={isLoading}
                onManageAgents={handleManageAgents}
                onAgentAction={handleAgentAction}
              />

              {/* Sprint Overview */}
              <SprintProgress
                sprint={sprint}
                burndownData={burndownData}
                availableSprints={[
                  { id: 'sprint-003', name: 'Sprint 3' },
                  { id: 'sprint-002', name: 'Sprint 2' },
                  { id: 'sprint-001', name: 'Sprint 1' },
                ]}
                selectedSprintId={sprint.id}
                isLoading={isLoading}
              />
            </div>

            {/* Right Column - Activity & Issue Summary */}
            <div className="space-y-6">
              {/* Issue Summary */}
              <IssueSummary
                summary={issueSummary}
                isLoading={isLoading}
                onViewAllIssues={handleViewAllIssues}
              />

              {/* Recent Activity */}
              <RecentActivity
                activities={allActivities}
                isLoading={isLoading}
                onViewAll={handleViewAllActivity}
                onActionClick={handleActionClick}
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
