import { useEffect, useCallback, useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useToast } from "@/components/molecules/Toast/use-toast";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
import * as Sentry from "@sentry/nextjs";
import {
  PublishAgentFormData,
  PublishAgentInfoInitialData,
  publishAgentSchemaFactory,
} from "./helpers";

export interface Props {
  onBack: () => void;
  onSuccess: (submissionData: any) => void;
  selectedAgentId: string | null;
  selectedAgentVersion: number | null;
  initialData?: PublishAgentInfoInitialData;
  isMarketplaceUpdate?: boolean;
}

export function useAgentInfoStep({
  onBack: _onBack,
  onSuccess,
  selectedAgentId,
  selectedAgentVersion,
  initialData,
  isMarketplaceUpdate = false,
}: Props) {
  const [agentId, setAgentId] = useState<string | null>(null);
  const [images, setImages] = useState<string[]>([]);
  const [isSubmitting, setIsSubmitting] = useState(false);

  const { toast } = useToast();
  const api = useBackendAPI();

  const form = useForm<PublishAgentFormData>({
    resolver: zodResolver(publishAgentSchemaFactory(isMarketplaceUpdate)),
    defaultValues: {
      changesSummary: "",
      title: "",
      subheader: "",
      slug: "",
      youtubeLink: "",
      category: "",
      description: "",
      recommendedScheduleCron: "",
      instructions: "",
      agentOutputDemo: "",
    },
  });

  useEffect(() => {
    if (initialData?.agent_id) {
      setAgentId(initialData.agent_id);
      setImages(
        Array.from(
          new Set([
            ...(initialData?.thumbnailSrc ? [initialData.thumbnailSrc] : []),
            ...(initialData.additionalImages || []),
          ]),
        ),
      );
      form.reset({
        changesSummary: isMarketplaceUpdate
          ? ""
          : initialData.changesSummary || "",
        title: initialData.title,
        subheader: initialData.subheader,
        slug: initialData.slug.toLocaleLowerCase().trim(),
        youtubeLink: initialData.youtubeLink,
        category: initialData.category,
        description: isMarketplaceUpdate ? "" : initialData.description,
        recommendedScheduleCron: initialData.recommendedScheduleCron || "",
        instructions: initialData.instructions || "",
        agentOutputDemo: initialData.agentOutputDemo || "",
      });
    }
  }, [initialData, form]);

  // Ensure agentId is set from selectedAgentId if initialData doesn't have it
  useEffect(() => {
    if (selectedAgentId && !agentId) {
      setAgentId(selectedAgentId);
    }
  }, [selectedAgentId, agentId]);

  const handleImagesChange = useCallback((newImages: string[]) => {
    setImages(newImages);
  }, []);

  async function handleFormSubmit(data: PublishAgentFormData) {
    // Validate that at least one image is present
    if (images.length === 0) {
      form.setError("root", {
        type: "manual",
        message: "At least one image is required",
      });
      return;
    }

    // Validate that an agent is selected before submission
    if (!selectedAgentId || !selectedAgentVersion) {
      toast({
        title: "Agent Selection Required",
        description: "Please select an agent before submitting to the store.",
        variant: "destructive",
      });
      return;
    }

    const categories = data.category ? [data.category] : [];
    const filteredCategories = categories.filter(Boolean);

    setIsSubmitting(true);

    try {
      const response = await api.createStoreSubmission({
        name: data.title,
        sub_heading: data.subheader,
        description: data.description,
        instructions: data.instructions || null,
        image_urls: images,
        video_url: data.youtubeLink || "",
        agent_output_demo_url: data.agentOutputDemo || "",
        agent_id: selectedAgentId,
        agent_version: selectedAgentVersion,
        slug: (data.slug || "").replace(/\s+/g, "-"),
        categories: filteredCategories,
        recommended_schedule_cron: data.recommendedScheduleCron || null,
        changes_summary: data.changesSummary || null,
      } as any);

      onSuccess(response);
    } catch (error) {
      Sentry.captureException(error);
      toast({
        title: "Submit Agent Error",
        description:
          (error instanceof Error ? error.message : undefined) ||
          "An error occurred while submitting the agent. Please try again.",
        duration: 3000,
        variant: "destructive",
      });
    } finally {
      setIsSubmitting(false);
    }
  }

  return {
    form,
    agentId,
    images,
    isSubmitting,
    initialImages: images,
    initialSelectedImage: initialData?.thumbnailSrc || null,
    handleImagesChange,
    handleSubmit: form.handleSubmit(handleFormSubmit),
  };
}
