import { useState, useEffect, useRef, useCallback } from "react";
import { submitContentJob } from "../api/contentJobs";

type JobStatus = "idle" | "queued" | "running" | "done" | "failed";

interface ContentJobState {
  jobId: string | null;
  status: JobStatus;
  progress: number;
  resultAssetId: string | null;
  errorMessage: string | null;
}

const INITIAL_STATE: ContentJobState = {
  jobId: null,
  status: "idle",
  progress: 0,
  resultAssetId: null,
  errorMessage: null,
};

function statusToProgress(status: string): number {
  switch (status) {
    case "queued":
      return 5;
    case "running":
      return 50;
    case "done":
      return 100;
    case "failed":
      return 0;
    default:
      return 0;
  }
}

export function useContentJob(companyId: string | null) {
  const [state, setState] = useState<ContentJobState>(INITIAL_STATE);
  const eventSourceRef = useRef<EventSource | null>(null);

  const closeEventSource = useCallback(() => {
    if (eventSourceRef.current) {
      eventSourceRef.current.close();
      eventSourceRef.current = null;
    }
  }, []);

  useEffect(() => {
    return () => {
      closeEventSource();
    };
  }, [closeEventSource]);

  const submit = useCallback(
    async (jobType: string, input: Record<string, unknown>, sourceTaskId?: string | null) => {
      if (!companyId) return;

      closeEventSource();
      setState({ ...INITIAL_STATE, status: "queued", progress: 5 });

      const result = await submitContentJob(companyId, jobType, input, sourceTaskId);
      const jobId = result.jobId;

      setState((prev) => ({ ...prev, jobId, status: "queued", progress: 5 }));

      const url = `/api/companies/${companyId}/content-jobs/${jobId}/events`;
      const es = new EventSource(url, { withCredentials: true });
      eventSourceRef.current = es;

      es.addEventListener("status", (e: MessageEvent) => {
        const data = JSON.parse(e.data as string) as {
          status?: string;
          progress?: number;
          resultAssetId?: string | null;
          errorMessage?: string | null;
        };
        const status = (data.status ?? "queued") as JobStatus;
        const progress =
          typeof data.progress === "number"
            ? data.progress
            : statusToProgress(status);

        setState((prev) => ({
          ...prev,
          status,
          progress,
          resultAssetId: data.resultAssetId ?? prev.resultAssetId,
          errorMessage: data.errorMessage ?? prev.errorMessage,
        }));

        if (status === "done" || status === "failed") {
          closeEventSource();
        }
      });

      es.addEventListener("error", () => {
        closeEventSource();
        setState((prev) => ({
          ...prev,
          status: "failed",
          errorMessage: prev.errorMessage ?? "Connection error",
        }));
      });
    },
    [companyId, closeEventSource],
  );

  const reset = useCallback(() => {
    closeEventSource();
    setState(INITIAL_STATE);
  }, [closeEventSource]);

  return { ...state, submit, reset };
}
