"use client";

/**
 * Aggregated Dashboard Page
 * Displays data from multiple federated instances in a unified view
 */

import { useState, useEffect } from "react";
import { AggregatedDataGrid } from "@/components/federation/AggregatedDataGrid";
import type { FederatedTask, FederatedEvent } from "@/components/federation/types";
import {
  fetchConnections,
  FederationConnectionStatus,
  type ConnectionDetails,
} from "@/lib/api/federation";
import { sendFederatedQuery, pollForQueryResponse } from "@/lib/api/federation-queries";
import type { Task, Event } from "@mosaic/shared";

export default function AggregatedDashboardPage(): React.JSX.Element {
  const [tasks, setTasks] = useState<FederatedTask[]>([]);
  const [events, setEvents] = useState<FederatedEvent[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [connections, setConnections] = useState<ConnectionDetails[]>([]);

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

  async function loadAggregatedData(): Promise<void> {
    setIsLoading(true);
    setError(null);

    try {
      // Fetch all active connections
      const allConnections = await fetchConnections(FederationConnectionStatus.ACTIVE);
      setConnections(allConnections);

      if (allConnections.length === 0) {
        setIsLoading(false);
        return;
      }

      // Query each connection for tasks and events
      const allTasks: FederatedTask[] = [];
      const allEvents: FederatedEvent[] = [];
      const errors: string[] = [];

      for (const connection of allConnections) {
        try {
          // Query tasks
          if (connection.remoteCapabilities.supportsQuery) {
            const taskQueryMessage = await sendFederatedQuery(connection.id, "get tasks", {
              limit: 10,
            });

            // Poll for the response instead of using setTimeout
            const taskResponse = await pollForQueryResponse(taskQueryMessage.id, {
              pollInterval: 500,
              timeout: 30000,
            });

            if (taskResponse.response) {
              const responseData = taskResponse.response as { type?: string; data?: Task[] };
              const responseTasks = responseData.data ?? [];
              const federatedTasks = responseTasks.map((task) => ({
                task,
                provenance: {
                  instanceId: connection.remoteInstanceId,
                  instanceName:
                    (connection.metadata.name as string | undefined) ?? connection.remoteUrl,
                  instanceUrl: connection.remoteUrl,
                  timestamp: new Date().toISOString(),
                },
              }));
              allTasks.push(...federatedTasks);
            }

            // Query events
            const eventQueryMessage = await sendFederatedQuery(connection.id, "get events", {
              limit: 10,
            });

            // Poll for the response
            const eventResponse = await pollForQueryResponse(eventQueryMessage.id, {
              pollInterval: 500,
              timeout: 30000,
            });

            if (eventResponse.response) {
              const responseData = eventResponse.response as { type?: string; data?: Event[] };
              const responseEvents = responseData.data ?? [];
              const federatedEvents = responseEvents.map((event) => ({
                event,
                provenance: {
                  instanceId: connection.remoteInstanceId,
                  instanceName:
                    (connection.metadata.name as string | undefined) ?? connection.remoteUrl,
                  instanceUrl: connection.remoteUrl,
                  timestamp: new Date().toISOString(),
                },
              }));
              allEvents.push(...federatedEvents);
            }
          }
        } catch (err) {
          const errorMessage = err instanceof Error ? err.message : "Unknown error";
          const instanceName =
            (connection.metadata.name as string | undefined) ?? connection.remoteUrl;
          errors.push(`Unable to reach ${instanceName}: ${errorMessage}`);
        }
      }

      setTasks(allTasks);
      setEvents(allEvents);

      if (errors.length > 0 && allTasks.length === 0 && allEvents.length === 0) {
        setError(errors.join(", "));
      }
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : "Unable to load connections";
      setError(errorMessage);
    } finally {
      setIsLoading(false);
    }
  }

  async function handleRefresh(): Promise<void> {
    await loadAggregatedData();
  }

  return (
    <main className="container mx-auto px-4 py-8">
      {/* Header */}
      <div className="mb-8 flex items-center justify-between">
        <div>
          <h1 className="text-3xl font-bold text-gray-900">Aggregated Dashboard</h1>
          <p className="text-gray-600 mt-2">View tasks and events from all connected instances</p>
        </div>
        <button
          onClick={handleRefresh}
          disabled={isLoading}
          className="px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
        >
          {isLoading ? "Loading..." : "Refresh"}
        </button>
      </div>

      {/* Connection status */}
      {!isLoading && connections.length > 0 && (
        <div className="mb-6">
          <p className="text-sm text-gray-600">
            Connected to <span className="font-medium text-gray-900">{connections.length}</span>{" "}
            {connections.length === 1 ? "instance" : "instances"}
          </p>
        </div>
      )}

      {/* Connection warning */}
      {!isLoading && connections.length === 0 && (
        <div className="mb-6 p-4 bg-yellow-50 border border-yellow-200 rounded-lg">
          <p className="text-sm text-yellow-800">
            No active connections found. Please visit the{" "}
            <a href="/federation/connections" className="font-medium underline">
              Connection Manager
            </a>{" "}
            to connect to remote instances.
          </p>
        </div>
      )}

      {/* Data grid */}
      <AggregatedDataGrid
        tasks={tasks}
        events={events}
        isLoading={isLoading}
        {...(error !== null && { error })}
      />
    </main>
  );
}
