import React, {useEffect, useRef, useState} from 'react';
import {BundleBacktestRequest, LightBacktestResponse, Ticker, Timeframe} from '../../generated/ManagingApiTypes';
import {BacktestClient} from '../../generated/ManagingApi';
import useApiUrlStore from '../../app/store/apiStore';
import Toast from '../../components/mollecules/Toast/Toast';
import {useQuery} from '@tanstack/react-query';
import * as signalR from '@microsoft/signalr';
import AuthorizedApiBase from '../../generated/AuthorizedApiBase';
import BacktestTable from '../../components/organism/Backtest/backtestTable';

interface BundleRequestModalProps {
  open: boolean;
  onClose: () => void;
  bundle: BundleBacktestRequest | null;
}

const BundleRequestModal: React.FC<BundleRequestModalProps> = ({ open, onClose, bundle }) => {
  const { apiUrl } = useApiUrlStore();
  const [backtests, setBacktests] = useState<LightBacktestResponse[]>([]);
  const signalRRef = useRef<any>(null);

  const {
    data: queryBacktests,
    isLoading,
    error: queryError,
    refetch
  } = useQuery({
    queryKey: ['bundle-backtests', bundle?.requestId],
    queryFn: async () => {
      if (!open || !bundle) return [];
      const client = new BacktestClient({} as any, apiUrl);
      const res = await client.backtest_GetBacktestsByRequestId(bundle.requestId);
      if (!res) return [];
      return res.map((b: any) => {
        // Map enums for ticker and timeframe
        if (b.config) {
          if (typeof b.config.ticker === 'number') {
            b.config.ticker = Ticker[b.config.ticker as keyof typeof Ticker];
          }
          if (typeof b.config.timeframe === 'number') {
            b.config.timeframe = Timeframe[b.config.timeframe as keyof typeof Timeframe];
          }
        }
        return {
          id: b.id,
          config: b.config,
          finalPnl: b.finalPnl,
          winRate: b.winRate,
          growthPercentage: b.growthPercentage,
          hodlPercentage: b.hodlPercentage,
          startDate: b.startDate,
          endDate: b.endDate,
          maxDrawdown: b.maxDrawdown ?? null,
          fees: b.fees,
          sharpeRatio: b.sharpeRatio ?? null,
          score: b.score ?? 0,
          scoreMessage: b.scoreMessage ?? '',
        };
      });
    },
    enabled: !!open && !!bundle,
    refetchOnWindowFocus: false,
  });
  useEffect(() => {
    if (queryBacktests) setBacktests(queryBacktests);
  }, [queryBacktests]);

  // SignalR live updates
  useEffect(() => {
    if (!open || !bundle) return;
    if (bundle.status !== 'Pending' && bundle.status !== 'Running') return;
    let connection: any = null;
    let connectionId: string = '';
    let unsubscribed = false;
    (async () => {
      try {
        connection = new signalR.HubConnectionBuilder()
          .withUrl(`${apiUrl.replace(/\/$/, '')}/backtestHub`)
          .withAutomaticReconnect()
          .build();
        await connection.start();
        connectionId = connection.connectionId;
        // Subscribe to bundle updates
        const authBase = new AuthorizedApiBase({} as any);
        let fetchOptions: any = {
          method: 'POST',
          headers: { 'X-SignalR-ConnectionId': connectionId },
        };
        fetchOptions = await authBase.transformOptions(fetchOptions);
        await fetch(`${apiUrl}/backtest/Bundle/Subscribe?requestId=${bundle.requestId}`, fetchOptions);
        connection.on('BundleBacktestUpdate', (result: LightBacktestResponse) => {
          // Map enums if needed
          if (result.config) {
            if (typeof result.config.ticker === 'number') {
              result.config.ticker = Ticker[result.config.ticker as keyof typeof Ticker];
            } else if (typeof result.config.ticker === 'string' && Ticker[result.config.ticker as keyof typeof Ticker]) {
              result.config.ticker = Ticker[result.config.ticker as keyof typeof Ticker];
            }
            if (typeof result.config.timeframe === 'number') {
              result.config.timeframe = Timeframe[result.config.timeframe as keyof typeof Timeframe];
            } else if (typeof result.config.timeframe === 'string' && Timeframe[result.config.timeframe as keyof typeof Timeframe]) {
              result.config.timeframe = Timeframe[result.config.timeframe as keyof typeof Timeframe];
            }
          }
          setBacktests((prev) => {
            if (prev.some((b) => b.id === result.id)) return prev;
            return [...prev, result];
          });
        });
        signalRRef.current = connection;
      } catch (e: any) {
        new Toast('Failed to subscribe to live updates', false);
      }
    })();
    return () => {
      unsubscribed = true;
      if (connection && connectionId) {
        (async () => {
          const authBase = new AuthorizedApiBase({} as any);
          let fetchOptions: any = {
            method: 'POST',
            headers: { 'X-SignalR-ConnectionId': connectionId },
          };
          fetchOptions = await authBase.transformOptions(fetchOptions);
          await fetch(`${apiUrl}/backtest/Bundle/Unsubscribe?requestId=${bundle.requestId}`, fetchOptions);
        })();
      }
      if (signalRRef.current) {
        signalRRef.current.stop();
        signalRRef.current = null;
      }
    };
  }, [open, bundle, apiUrl]);

  if (!open || !bundle) return null;

  return (
    <div className="modal modal-open">
      <div className="modal-box max-w-4xl">
        <h3 className="font-bold text-lg mb-2">Bundle: {bundle.name}</h3>
        <div className="mb-2 text-sm">
          <div><b>Request ID:</b> <span className="font-mono text-xs">{bundle.requestId}</span></div>
          <div><b>Status:</b> <span className={`badge badge-sm ml-1`}>{bundle.status}</span></div>
          <div><b>Created:</b> {bundle.createdAt ? new Date(bundle.createdAt).toLocaleString() : '-'}</div>
          <div><b>Completed:</b> {bundle.completedAt ? new Date(bundle.completedAt).toLocaleString() : '-'}</div>
        </div>
        <div className="divider">Backtest Results</div>
        {isLoading ? (
          <div>Loading backtests...</div>
        ) : queryError ? (
          <div className="text-error">{(queryError as any)?.message || 'Failed to fetch backtests'}</div>
        ) : (
          <BacktestTable list={backtests} />
        )}
        <div className="modal-action">
          <button className="btn" onClick={onClose}>Close</button>
        </div>
      </div>
    </div>
  );
};

export default BundleRequestModal; 