import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import { TaskProgress } from "@/types";
import { useState, useMemo } from "react";
import { ChevronDown, ChevronRight, CheckCircle2, XCircle, Loader2, AlertCircle } from "lucide-react";
import { cn } from "@/lib/utils";

interface RawDataViewerProps {
  data: unknown[];
  tasks: TaskProgress[];
  status: 'idle' | 'fetching' | 'complete' | 'error';
}

export function RawDataViewer({ data, tasks, status }: RawDataViewerProps) {
  const groupedProviders = useMemo(() => {
    // 1. Group Data by Source
    const dataGroups: Record<string, unknown[]> = {};
    if (Array.isArray(data)) {
      data.forEach((item: any) => {
        // Normalize source: lowercase
        // In SessionDataDto, provider is the key. item.source is legacy/fallback.
        const source = (item.provider || item.source || 'unknown').toLowerCase();
        if (!dataGroups[source]) dataGroups[source] = [];
        // We push the whole item which contains { provider, data_type, data_payload }
        dataGroups[source].push(item);
      });
    }

    // 2. Map Tasks to Providers
    const providerMap = new Map<string, {
      name: string;
      status: string;
      details?: string;
      data: unknown[];
    }>();

    // Populate from Tasks first (as they represent the current execution plan)
    tasks.forEach(task => {
      // Task name format: "provider:symbol" or just "provider"
      const providerName = task.task_name.split(':')[0].toLowerCase();
      providerMap.set(providerName, {
        name: providerName,
        status: task.status,
        details: task.details,
        data: dataGroups[providerName] || []
      });
    });

    // Populate remaining data sources (historical or pre-fetched) that might not have a task
    Object.keys(dataGroups).forEach(source => {
      if (!providerMap.has(source)) {
        providerMap.set(source, {
          name: source,
          status: 'completed', // If we have data, assume it's done
          details: 'Data loaded from cache/db',
          data: dataGroups[source]
        });
      }
    });

    return Array.from(providerMap.values());
  }, [data, tasks]);

  if (groupedProviders.length === 0 && status === 'error') {
    return (
      <div className="flex items-center justify-center h-[100px] text-destructive border rounded-lg border-destructive/50 bg-destructive/10 gap-2">
        <AlertCircle className="h-5 w-5" />
        <span>Error fetching data.</span>
      </div>
    );
  }

  if (groupedProviders.length === 0 && status === 'fetching') {
      return (
          <div className="flex items-center justify-center h-[100px] text-muted-foreground gap-2">
              <Loader2 className="h-4 w-4 animate-spin" />
              <span>Waiting for providers...</span>
          </div>
      )
  }

  return (
    <div className="space-y-4">
      {groupedProviders.map(provider => (
        <ProviderSection 
          key={provider.name} 
          name={provider.name}
          status={provider.status}
          details={provider.details}
          data={provider.data}
        />
      ))}
      
      {groupedProviders.length === 0 && status === 'complete' && (
         <div className="text-center p-8 text-muted-foreground border rounded-lg border-dashed">
             No data providers found.
         </div>
      )}
    </div>
  );
}

function ProviderSection({ 
    name, 
    status, 
    details, 
    data 
}: { 
    name: string; 
    status: string; 
    details?: string; 
    data: unknown[] 
}) {
  const [isOpen, setIsOpen] = useState(false);

  // Auto-open if there is an error to show details, otherwise keep closed to save space
  // or keep open if it's the only one? Let's default to closed but maybe open if it has interesting data?
  // User said "generally collapsed", so default false.

  return (
    <Card className={cn("transition-all", isOpen ? "ring-1 ring-primary/20" : "")}>
      <CardHeader 
        className="py-3 px-4 cursor-pointer hover:bg-muted/50 transition-colors select-none"
        onClick={() => setIsOpen(!isOpen)}
      >
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            {isOpen ? <ChevronDown className="h-4 w-4 text-muted-foreground"/> : <ChevronRight className="h-4 w-4 text-muted-foreground"/>}
            
            <div className="flex flex-col">
                <div className="flex items-center gap-2">
                    <CardTitle className="text-base font-semibold capitalize leading-none">
                    {name}
                    </CardTitle>
                    <StatusBadge status={status} />
                </div>
            </div>
          </div>

          <div className="flex items-center gap-4 text-sm text-muted-foreground">
             <span className="hidden sm:inline-block text-xs bg-secondary px-2 py-1 rounded-md">
                {data.length} records
             </span>
          </div>
        </div>
        
        {/* Progress/Details Text */}
        {(details || status === 'in_progress') && (
             <div className="ml-7 mt-1 text-xs text-muted-foreground truncate max-w-[600px]">
                {details}
             </div>
        )}
      </CardHeader>

      {isOpen && (
        <CardContent className="pt-0 px-4 pb-4">
            <div className="mt-2 border rounded-md bg-muted/30">
                {data.length > 0 ? (
                    <ScrollArea className="h-[300px] w-full p-4">
                        {/* Show structured data if available */}
                        <div className="space-y-4">
                           {data.map((item: any, idx) => (
                               <div key={idx} className="space-y-1">
                                   <div className="flex items-center gap-2">
                                     <Badge variant="outline" className="text-[10px] h-5">{item.data_type || 'unknown'}</Badge>
                                     <span className="text-xs text-muted-foreground">{item.created_at || ''}</span>
                                   </div>
                                   <pre className="text-xs font-mono break-all whitespace-pre-wrap text-foreground/80 bg-background/50 p-2 rounded border">
                                       {/* If item.data_payload exists, show it. Otherwise show item (legacy) */}
                                       {JSON.stringify(item.data_payload !== undefined ? item.data_payload : item, null, 2)}
                                   </pre>
                               </div>
                           ))}
                        </div>
                    </ScrollArea>
                ) : (
                    <div className="p-8 text-center text-sm text-muted-foreground">
                        {status === 'failed' 
                            ? "No data generated due to failure." 
                            : "No data records available yet."}
                    </div>
                )}
            </div>
        </CardContent>
      )}
    </Card>
  );
}

function StatusBadge({ status }: { status: string }) {
    const s = status.toLowerCase();
    if (s === 'completed' || s === 'success') {
        return <Badge variant="outline" className="bg-green-500/10 text-green-600 border-green-500/20 hover:bg-green-500/20 gap-1"><CheckCircle2 className="h-3 w-3"/> Success</Badge>;
    }
    if (s === 'failed' || s === 'error') {
        return <Badge variant="destructive" className="gap-1"><XCircle className="h-3 w-3"/> Failed</Badge>;
    }
    if (s === 'in_progress' || s === 'running') {
        return <Badge variant="secondary" className="gap-1 animate-pulse"><Loader2 className="h-3 w-3 animate-spin"/> Running</Badge>;
    }
    return <Badge variant="outline" className="text-muted-foreground">{status}</Badge>;
}
