import { useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { toast } from "@/hooks/use-toast";
import {
  getWorkflowTemplateDefinition,
  type Workflow,
} from "@features/workflow/data/workflow-data";
import {
  createWorkflowFromTemplate,
  deleteWorkflow,
} from "@features/workflow/lib/workflow-storage";
import { fetchWorkflowVersions } from "@features/workflow/lib/workflow-storage-api";
import { getWorkflowRouteRef } from "@features/workflow/lib/workflow-storage-helpers";
import { type WorkflowGalleryTab } from "./types";

interface WorkflowGalleryActionsArgs {
  newFolderName: string;
  setNewFolderName: (value: string) => void;
  setSelectedTab: (value: WorkflowGalleryTab) => void;
  setShowNewFolderDialog: (value: boolean) => void;
  setShowFilterPopover: (value: boolean) => void;
}

const STARTER_TEMPLATE_IDS = ["template-python-agent"];
const WORKFLOW_FALLBACK_EXPORT_NAME = "workflow";

const toDownloadBasename = (workflowName: string): string => {
  const normalized = workflowName.trim().replace(/\s+/g, "-").toLowerCase();
  return normalized.length > 0 ? normalized : WORKFLOW_FALLBACK_EXPORT_NAME;
};

const getLangGraphSource = (
  workflowName: string,
  graph: Record<string, unknown>,
): string => {
  const graphFormat =
    typeof graph.format === "string" ? graph.format : "unknown";
  const graphSource = graph.source;

  if (
    graphFormat === "langgraph-script" &&
    typeof graphSource === "string" &&
    graphSource.trim().length > 0
  ) {
    return graphSource;
  }

  throw new Error(
    `Workflow '${workflowName}' uses unsupported format '${graphFormat}'. Only LangGraph script versions can be exported.`,
  );
};

export const resolveWorkflowPythonSource = async (
  workflow: Workflow,
): Promise<string> => {
  const templateDefinition = getWorkflowTemplateDefinition(workflow.id);
  if (
    templateDefinition &&
    typeof templateDefinition.script === "string" &&
    templateDefinition.script.trim().length > 0
  ) {
    return templateDefinition.script;
  }

  const versions = await fetchWorkflowVersions(workflow.id);
  if (versions.length === 0) {
    throw new Error(`Workflow '${workflow.name}' has no versions to export.`);
  }

  const latestVersion = versions.reduce((latest, current) =>
    current.version > latest.version ? current : latest,
  );

  if (!latestVersion.graph || typeof latestVersion.graph !== "object") {
    throw new Error(`Workflow '${workflow.name}' has no exportable source.`);
  }

  return getLangGraphSource(workflow.name, latestVersion.graph);
};

export const useWorkflowGalleryActions = (
  state: WorkflowGalleryActionsArgs,
) => {
  const navigate = useNavigate();

  const handleOpenWorkflow = useCallback(
    (workflowId: string) => {
      navigate(`/workflow-canvas/${workflowId}`);
    },
    [navigate],
  );

  const handleCreateFolder = useCallback(() => {
    toast({
      title: "Folder creation coming soon",
      description: state.newFolderName
        ? `We'll create "${state.newFolderName}" once persistence is wired up.`
        : "Folder creation will be available in a future update.",
    });

    state.setNewFolderName("");
    state.setShowNewFolderDialog(false);
  }, [state]);

  const handleUseTemplate = useCallback(
    async (templateId: string) => {
      try {
        const workflow = await createWorkflowFromTemplate(templateId);
        if (!workflow) {
          toast({
            title: "Template unavailable",
            description: "We couldn't find that template. Please try another.",
            variant: "destructive",
          });
          return;
        }

        state.setSelectedTab("all");

        toast({
          title: "Template copied",
          description: `"${workflow.name}" has been added to your workspace.`,
        });

        handleOpenWorkflow(getWorkflowRouteRef(workflow));
      } catch (error) {
        toast({
          title: "Failed to create workflow from template",
          description:
            error instanceof Error ? error.message : "Unknown error occurred",
          variant: "destructive",
        });
      }
    },
    [handleOpenWorkflow, state],
  );

  const handleImportStarterPack = useCallback(async () => {
    try {
      const results = await Promise.allSettled(
        STARTER_TEMPLATE_IDS.map((templateId) =>
          createWorkflowFromTemplate(templateId),
        ),
      );
      const importedCount = results.filter(
        (result) => result.status === "fulfilled" && result.value,
      ).length;

      if (importedCount === 0) {
        toast({
          title: "Starter pack unavailable",
          description:
            "No starter workflows were imported. Please try again later.",
          variant: "destructive",
        });
        return;
      }

      state.setSelectedTab("all");

      toast({
        title: "Starter pack imported",
        description: `${importedCount} Python workflow${importedCount === 1 ? "" : "s"} added to your workspace.`,
      });
    } catch (error) {
      toast({
        title: "Failed to import starter pack",
        description:
          error instanceof Error ? error.message : "Unknown error occurred",
        variant: "destructive",
      });
    }
  }, [state]);

  const handleExportWorkflow = useCallback(async (workflow: Workflow) => {
    try {
      const source = await resolveWorkflowPythonSource(workflow);
      const fileBaseName = toDownloadBasename(workflow.name);
      const blob = new Blob([source], { type: "text/x-python" });
      const url = URL.createObjectURL(blob);
      const anchor = document.createElement("a");
      anchor.href = url;
      anchor.download = `${fileBaseName}.py`;
      anchor.click();
      URL.revokeObjectURL(url);

      toast({
        title: "Workflow exported",
        description: `Downloaded ${fileBaseName}.py`,
      });
    } catch (error) {
      toast({
        title: "Export failed",
        description:
          error instanceof Error ? error.message : "Unable to export workflow.",
        variant: "destructive",
      });
    }
  }, []);

  const handleDeleteWorkflow = useCallback(
    async (workflowId: string, workflowName: string) => {
      try {
        await deleteWorkflow(workflowId);
        toast({
          title: "Workflow deleted",
          description: `"${workflowName}" has been removed from your workspace.`,
        });
      } catch (error) {
        toast({
          title: "Failed to delete workflow",
          description:
            error instanceof Error ? error.message : "Unknown error occurred",
          variant: "destructive",
        });
      }
    },
    [],
  );

  const handleApplyFilters = useCallback(() => {
    toast({
      title: "Filters applied",
      description:
        "Filter changes will affect the gallery once data wiring is complete.",
    });
    state.setShowFilterPopover(false);
  }, [state]);

  return {
    handleOpenWorkflow,
    handleCreateFolder,
    handleUseTemplate,
    handleImportStarterPack,
    handleExportWorkflow,
    handleDeleteWorkflow,
    handleApplyFilters,
  };
};
