'use client';

import { useState, useEffect } from 'react';
import { useParams, useRouter } from 'next/navigation';
import { PageWrapper } from '@/components/shared/state/PageWrapper';
import { RaceStewardingTemplate, StewardingTab } from '@/templates/RaceStewardingTemplate';
import { RacesApiClient } from '@/lib/api/races/RacesApiClient';
import { ProtestsApiClient } from '@/lib/api/protests/ProtestsApiClient';
import { PenaltiesApiClient } from '@/lib/api/penalties/PenaltiesApiClient';
import { EnhancedErrorReporter } from '@/lib/infrastructure/EnhancedErrorReporter';
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
import { useLeagueMemberships } from "@/lib/hooks/league/useLeagueMemberships";
import { useEffectiveDriverId } from "@/lib/hooks/useEffectiveDriverId";
import { LeagueRoleUtility } from '@/lib/utilities/LeagueRoleUtility';
import { Gavel } from 'lucide-react';

// Define the view model structure locally to avoid type issues
interface RaceStewardingViewModel {
  race: any;
  league: any;
  protests: any[];
  penalties: any[];
  driverMap: Record<string, any>;
  pendingProtests: any[];
  resolvedProtests: any[];
  pendingCount: number;
  resolvedCount: number;
  penaltiesCount: number;
}

export default function RaceStewardingPage() {
  const router = useRouter();
  const params = useParams();
  const raceId = params.id as string;
  const currentDriverId = useEffectiveDriverId() || '';
  
  // Data state
  const [pageData, setPageData] = useState<RaceStewardingViewModel | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);
  
  // UI State
  const [activeTab, setActiveTab] = useState<StewardingTab>('pending');

  // Fetch data on mount and when raceId/currentDriverId changes
  useEffect(() => {
    async function fetchData() {
      if (!raceId) return;
      
      try {
        setIsLoading(true);
        setError(null);
        
        // Manual wiring: create dependencies
        const baseUrl = getWebsiteApiBaseUrl();
        const logger = new ConsoleLogger();
        const errorReporter = new EnhancedErrorReporter(logger, {
          showUserNotifications: true,
          logToConsole: true,
          reportToExternal: process.env.NODE_ENV === 'production',
        });

        // Create API clients
        const racesApiClient = new RacesApiClient(baseUrl, errorReporter, logger);
        const protestsApiClient = new ProtestsApiClient(baseUrl, errorReporter, logger);
        const penaltiesApiClient = new PenaltiesApiClient(baseUrl, errorReporter, logger);

        // Fetch data in parallel
        const [raceDetail, protests, penalties] = await Promise.all([
          racesApiClient.getDetail(raceId, currentDriverId),
          protestsApiClient.getRaceProtests(raceId),
          penaltiesApiClient.getRacePenalties(raceId),
        ]);

        // Transform data to match view model structure
        const data: RaceStewardingViewModel = {
          race: raceDetail.race,
          league: raceDetail.league,
          protests: protests.protests.map(p => ({
            id: p.id,
            protestingDriverId: p.protestingDriverId,
            accusedDriverId: p.accusedDriverId,
            incident: {
              lap: p.lap,
              description: p.description,
            },
            filedAt: p.filedAt,
            status: p.status,
          })),
          penalties: penalties.penalties,
          driverMap: { ...protests.driverMap, ...penalties.driverMap },
          pendingProtests: [],
          resolvedProtests: [],
          pendingCount: 0,
          resolvedCount: 0,
          penaltiesCount: 0,
        };

        // Calculate derived properties
        data.pendingProtests = data.protests.filter(p => p.status === 'pending' || p.status === 'under_review');
        data.resolvedProtests = data.protests.filter(p =>
          p.status === 'upheld' ||
          p.status === 'dismissed' ||
          p.status === 'withdrawn'
        );
        data.pendingCount = data.pendingProtests.length;
        data.resolvedCount = data.resolvedProtests.length;
        data.penaltiesCount = data.penalties.length;
        
        if (data) {
          setPageData(data);
        } else {
          setPageData(null);
        }
      } catch (err) {
        setError(err instanceof Error ? err : new Error('Failed to fetch stewarding data'));
        setPageData(null);
      } finally {
        setIsLoading(false);
      }
    }
    
    fetchData();
  }, [raceId, currentDriverId]);

  // Fetch membership
  const { data: membershipsData } = useLeagueMemberships(pageData?.league?.id || '', currentDriverId || '');
  const currentMembership = membershipsData?.members.find(m => m.driverId === currentDriverId);
  const isAdmin = currentMembership ? LeagueRoleUtility.isLeagueAdminOrHigherRole(currentMembership.role) : false;

  // Actions
  const handleBack = () => {
    router.push(`/races/${raceId}`);
  };

  const handleReviewProtest = (protestId: string) => {
    // Navigate to protest review page
    router.push(`/leagues/${pageData?.league?.id}/stewarding/protests/${protestId}`);
  };

  // Transform data for template
  const templateData = pageData ? {
    race: pageData.race,
    league: pageData.league,
    pendingProtests: pageData.pendingProtests,
    resolvedProtests: pageData.resolvedProtests,
    penalties: pageData.penalties,
    driverMap: pageData.driverMap,
    pendingCount: pageData.pendingCount,
    resolvedCount: pageData.resolvedCount,
    penaltiesCount: pageData.penaltiesCount,
  } : undefined;

  const retry = async () => {
    try {
      setIsLoading(true);
      setError(null);
      
      // Manual wiring: create dependencies
      const baseUrl = getWebsiteApiBaseUrl();
      const logger = new ConsoleLogger();
      const errorReporter = new EnhancedErrorReporter(logger, {
        showUserNotifications: true,
        logToConsole: true,
        reportToExternal: process.env.NODE_ENV === 'production',
      });

      // Create API clients
      const racesApiClient = new RacesApiClient(baseUrl, errorReporter, logger);
      const protestsApiClient = new ProtestsApiClient(baseUrl, errorReporter, logger);
      const penaltiesApiClient = new PenaltiesApiClient(baseUrl, errorReporter, logger);

      // Fetch data in parallel
      const [raceDetail, protests, penalties] = await Promise.all([
        racesApiClient.getDetail(raceId, currentDriverId),
        protestsApiClient.getRaceProtests(raceId),
        penaltiesApiClient.getRacePenalties(raceId),
      ]);

      // Transform data to match view model structure
      const data: RaceStewardingViewModel = {
        race: raceDetail.race,
        league: raceDetail.league,
        protests: protests.protests.map(p => ({
          id: p.id,
          protestingDriverId: p.protestingDriverId,
          accusedDriverId: p.accusedDriverId,
          incident: {
            lap: p.lap,
            description: p.description,
          },
          filedAt: p.filedAt,
          status: p.status,
        })),
        penalties: penalties.penalties,
        driverMap: { ...protests.driverMap, ...penalties.driverMap },
        pendingProtests: [],
        resolvedProtests: [],
        pendingCount: 0,
        resolvedCount: 0,
        penaltiesCount: 0,
      };

      // Calculate derived properties
      data.pendingProtests = data.protests.filter(p => p.status === 'pending' || p.status === 'under_review');
      data.resolvedProtests = data.protests.filter(p =>
        p.status === 'upheld' ||
        p.status === 'dismissed' ||
        p.status === 'withdrawn'
      );
      data.pendingCount = data.pendingProtests.length;
      data.resolvedCount = data.resolvedProtests.length;
      data.penaltiesCount = data.penalties.length;
      
      if (data) {
        setPageData(data);
      }
    } catch (err) {
      setError(err instanceof Error ? err : new Error('Failed to fetch stewarding data'));
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <PageWrapper
      data={pageData}
      isLoading={isLoading}
      error={error}
      retry={retry}
      Template={({ data }) => (
        <RaceStewardingTemplate
          stewardingData={templateData}
          isLoading={false}
          error={null}
          onBack={handleBack}
          onReviewProtest={handleReviewProtest}
          isAdmin={isAdmin}
          activeTab={activeTab}
          setActiveTab={setActiveTab}
        />
      )}
      loading={{ variant: 'skeleton', message: 'Loading stewarding data...' }}
      errorConfig={{ variant: 'full-screen' }}
      empty={{
        icon: Gavel,
        title: 'No stewarding data',
        description: 'No protests or penalties for this race',
        action: { label: 'Back to Race', onClick: handleBack }
      }}
    />
  );
}