import { useState } from "react";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog";
import { type Provider, OnboardingStep } from "./types";
import { ProviderSelectionStep } from "./provider-selection-step";
import { IngestionStep } from "./ingestion-step";
import { VerificationStep } from "./verification-step";
import { PROVIDER_CONFIGS } from "./provider-config";
import { Progress } from "../ui/progress";

interface OnboardingModalProps {
  isOpen: boolean;
  onClose: () => void;
  onComplete: () => void;
}

export function OnboardingModal({
  isOpen,
  onClose,
  onComplete,
}: OnboardingModalProps) {
  const [currentStep, setCurrentStep] = useState<OnboardingStep>(
    OnboardingStep.PROVIDER_SELECTION,
  );
  const [selectedProvider, setSelectedProvider] = useState<Provider>();
  const [ingestionStatus, setIngestionStatus] = useState<
    "idle" | "waiting" | "processing" | "complete" | "error"
  >("idle");
  const [verificationResult, setVerificationResult] = useState<string>();
  const [isCheckingRecall, setIsCheckingRecall] = useState(false);
  const [error, setError] = useState<string>();

  // Calculate progress
  const getProgress = () => {
    switch (currentStep) {
      case OnboardingStep.PROVIDER_SELECTION:
        return 33;
      case OnboardingStep.FIRST_INGESTION:
        return 66;
      case OnboardingStep.VERIFICATION:
        return 100;
      default:
        return 0;
    }
  };

  // Poll for ingestion status
  const pollIngestion = async () => {
    setIngestionStatus("waiting");

    try {
      const maxAttempts = 30; // 60 seconds (30 * 2s)
      let attempts = 0;

      // Store the timestamp when polling starts
      const startTime = Date.now();

      const poll = async (): Promise<boolean> => {
        if (attempts >= maxAttempts) {
          throw new Error("Ingestion timeout - please try again");
        }

        // Check for new ingestion logs from the last 5 minutes
        const response = await fetch("/api/v1/logs?limit=1");
        const data = await response.json();

        // Check if there's a recent ingestion (created after we started polling)
        if (data.logs && data.logs.length > 0) {
          const latestLog = data.logs[0];
          const logTime = new Date(latestLog.time).getTime();

          // If the log was created after we started polling, we found a new ingestion
          if (logTime >= startTime) {
            return true;
          }
        }

        await new Promise((resolve) => setTimeout(resolve, 2000));
        attempts++;

        return poll();
      };

      const success = await poll();

      if (success) {
        setIngestionStatus("complete");
        // Auto-advance to verification step after 2 seconds
        setTimeout(() => {
          setCurrentStep(OnboardingStep.VERIFICATION);
        }, 2000);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : "Unknown error occurred");
      setIngestionStatus("error");
    }
  };

  const handleProviderSelect = (provider: Provider) => {
    setSelectedProvider(provider);
  };

  const handleContinueFromProvider = () => {
    setCurrentStep(OnboardingStep.FIRST_INGESTION);
  };

  const handleStartWaiting = () => {
    pollIngestion();
  };

  const handleComplete = () => {
    setCurrentStep(OnboardingStep.COMPLETE);
    onComplete();
    onClose();
  };

  // Poll for recall logs to detect verification
  const pollRecallLogs = async () => {
    setIsCheckingRecall(true);

    try {
      const maxAttempts = 30; // 60 seconds
      let attempts = 0;
      const startTime = Date.now();

      const poll = async (): Promise<string | null> => {
        if (attempts >= maxAttempts) {
          throw new Error("Verification timeout - please try again");
        }

        // Check for new recall logs
        const response = await fetch("/api/v1/recall-logs?limit=1");
        const data = await response.json();

        // Check if there's a recent recall (created after we started polling)
        if (data.recallLogs && data.recallLogs.length > 0) {
          const latestRecall = data.recallLogs[0];
          const recallTime = new Date(latestRecall.createdAt).getTime();

          // If the recall was created after we started polling
          if (recallTime >= startTime) {
            // Return the query as verification result
            return latestRecall.query || "Recall detected successfully";
          }
        }

        await new Promise((resolve) => setTimeout(resolve, 2000));
        attempts++;

        return poll();
      };

      const result = await poll();

      if (result) {
        setVerificationResult(result);
        setIsCheckingRecall(false);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : "Unknown error occurred");
      setIsCheckingRecall(false);
    }
  };

  const getStepTitle = () => {
    switch (currentStep) {
      case OnboardingStep.PROVIDER_SELECTION:
        return "Step 1 of 3";
      case OnboardingStep.FIRST_INGESTION:
        return "Step 2 of 3";
      case OnboardingStep.VERIFICATION:
        return "Step 3 of 3";
      default:
        return "";
    }
  };

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="max-h-[90vh] max-w-3xl overflow-y-auto p-4">
        <DialogHeader>
          <div className="space-y-3">
            <DialogTitle className="text-2xl">Welcome to Core</DialogTitle>
            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <p className="text-muted-foreground text-sm">
                  {getStepTitle()}
                </p>
              </div>
              <Progress
                segments={[{ value: getProgress() }]}
                className="mb-2"
                color="#c15e50"
              />
            </div>
          </div>
        </DialogHeader>

        <div>
          {currentStep === OnboardingStep.PROVIDER_SELECTION && (
            <ProviderSelectionStep
              selectedProvider={selectedProvider}
              onSelectProvider={handleProviderSelect}
              onContinue={handleContinueFromProvider}
            />
          )}

          {currentStep === OnboardingStep.FIRST_INGESTION &&
            selectedProvider && (
              <IngestionStep
                providerName={PROVIDER_CONFIGS[selectedProvider].name}
                ingestionStatus={ingestionStatus}
                onStartWaiting={handleStartWaiting}
                error={error}
              />
            )}

          {currentStep === OnboardingStep.VERIFICATION && selectedProvider && (
            <VerificationStep
              providerName={PROVIDER_CONFIGS[selectedProvider].name}
              verificationResult={verificationResult}
              isCheckingRecall={isCheckingRecall}
              onStartChecking={pollRecallLogs}
              onComplete={handleComplete}
            />
          )}
        </div>
      </DialogContent>
    </Dialog>
  );
}
