"use client";

import React, { useEffect, useRef, useState, useCallback } from "react";
import { useRouter } from "next/navigation";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "@/store/store";
import {
  setWizardStep,
  setJobId,
  setPresentationId as setWizardPresentationId,
} from "@/store/slices/wizardSlice";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import {
  CheckCircle2,
  XCircle,
  RotateCcw,
  ChevronLeft,
  StopCircle,
} from "lucide-react";
import { HamsterLoader } from "@/components/ui/hamster-loader";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import Wrapper from "@/components/Wrapper";
import { WizardApi, JobStatus } from "../../services/api/wizard";

export default function WizardProgressPage() {
  const router = useRouter();
  const dispatch = useDispatch();
  const { jobId, presentationId } = useSelector((s: RootState) => s.wizard);

  const [progress, setProgress] = useState(0);
  const [message, setMessage] = useState("Initializing...");
  const [status, setStatus] = useState<string>("pending");
  const [error, setError] = useState<string | null>(null);
  const eventSourceRef = useRef<EventSource | null>(null);
  const pollingRef = useRef<NodeJS.Timeout | null>(null);

  // Auto-navigate when completed
  useEffect(() => {
    if (status === "completed" && presentationId) {
      const timer = setTimeout(() => {
        dispatch(setWizardStep(5));
        router.push(`/presentation?id=${presentationId}`);
      }, 1500);
      return () => clearTimeout(timer);
    }
  }, [status, presentationId, dispatch, router]);

  // Connect to SSE stream or fall back to polling
  useEffect(() => {
    if (!jobId) return;

    const connectSSE = () => {
      const es = new EventSource(`/api/v1/ppt/jobs/${jobId}/stream`);
      eventSourceRef.current = es;

      es.addEventListener("response", (event) => {
        try {
          const data = JSON.parse(event.data);
          if (data.type === "progress") {
            setProgress(data.progress ?? 0);
            setMessage(data.message ?? "Processing...");
            setStatus(data.status ?? "processing");

            if (data.status === "completed") {
              if (data.presentation_id) {
                dispatch(setWizardPresentationId(data.presentation_id));
              }
              es.close();
            }
            if (data.status === "failed") {
              setError(data.message || "Generation failed");
              es.close();
            }
          }
          if (data.type === "error") {
            setError(data.detail || "Unknown error");
            es.close();
          }
        } catch {
          // ignore parse errors
        }
      });

      es.onerror = () => {
        es.close();
        // Fall back to polling
        startPolling();
      };
    };

    const startPolling = () => {
      if (pollingRef.current) return;
      pollingRef.current = setInterval(async () => {
        try {
          const job = await WizardApi.getJobStatus(jobId);
          setProgress(job.progress);
          setMessage(job.progress_message || "Processing...");
          setStatus(job.status);

          if (job.status === "completed") {
            if (job.presentation_id) {
              dispatch(setWizardPresentationId(job.presentation_id));
            }
            clearInterval(pollingRef.current!);
            pollingRef.current = null;
          }
          if (job.status === "failed") {
            setError(job.error_message || "Generation failed");
            clearInterval(pollingRef.current!);
            pollingRef.current = null;
          }
        } catch {
          // continue polling
        }
      }, 3000);
    };

    connectSSE();

    return () => {
      eventSourceRef.current?.close();
      if (pollingRef.current) {
        clearInterval(pollingRef.current);
        pollingRef.current = null;
      }
    };
  }, [jobId, dispatch]);

  const handleCancel = async () => {
    if (!jobId) return;
    try {
      await WizardApi.cancelJob(jobId);
      dispatch(setJobId(null));
      dispatch(setWizardStep(3));
      router.push("/generate/outline");
    } catch {
      toast.error("Failed to cancel job");
    }
  };

  const handleRetry = () => {
    dispatch(setJobId(null));
    dispatch(setWizardStep(3));
    router.push("/generate/outline");
  };

  const isTerminal = status === "completed" || status === "failed";

  if (!jobId) {
    return (
      <Wrapper className="py-16 text-center">
        <p className="text-gray-500 mb-4">No generation in progress.</p>
        <Button variant="outline" onClick={() => router.push("/generate/outline")}>
          <ChevronLeft className="w-4 h-4 mr-1" />
          Back to Outline
        </Button>
      </Wrapper>
    );
  }

  return (
    <Wrapper className="py-16 max-w-2xl">
      <div className="text-center">
        {/* Icon */}
        <div className="mb-6">
          {status === "completed" ? (
            <CheckCircle2 className="w-16 h-16 text-green-500 mx-auto" />
          ) : status === "failed" ? (
            <XCircle className="w-16 h-16 text-red-500 mx-auto" />
          ) : (
            <HamsterLoader size="lg" />
          )}
        </div>

        {/* Title */}
        <h1 className="text-2xl font-semibold mb-2">
          {status === "completed"
            ? "Presentation Ready!"
            : status === "failed"
            ? "Generation Failed"
            : "Generating Presentation"}
        </h1>

        {/* Message */}
        <p
          className={cn(
            "text-sm mb-8",
            status === "failed" ? "text-red-600" : "text-gray-500"
          )}
        >
          {error || message}
        </p>

        {/* Progress Bar */}
        <div className="mb-2">
          <Progress value={progress} className="h-3" />
        </div>
        <p className="text-sm text-gray-400 mb-8">{progress}%</p>

        {/* Actions */}
        <div className="flex justify-center gap-3">
          {!isTerminal && (
            <Button
              variant="outline"
              onClick={handleCancel}
              className="rounded-full px-6"
            >
              <StopCircle className="w-4 h-4 mr-1" />
              Cancel
            </Button>
          )}
          {status === "failed" && (
            <Button
              onClick={handleRetry}
              className="rounded-full px-6 bg-[#5146E5] hover:bg-[#5146E5]/90 text-white"
            >
              <RotateCcw className="w-4 h-4 mr-1" />
              Retry
            </Button>
          )}
          {status === "completed" && presentationId && (
            <Button
              onClick={() => {
                dispatch(setWizardStep(5));
                router.push(`/presentation?id=${presentationId}`);
              }}
              className="rounded-full px-8 bg-[#5146E5] hover:bg-[#5146E5]/90 text-white"
            >
              Open Presentation
            </Button>
          )}
        </div>
      </div>
    </Wrapper>
  );
}
