import type { Session, SupabaseClient, User as SupabaseUser } from "@supabase/supabase-js";
import { useMutation } from "@tanstack/react-query";
import type { AxiosInstance } from "axios";
import { useState } from "react";
import { match } from "ts-pattern";
import { toast } from "../lib/toast";

interface AuthResponse {
  user: SupabaseUser | null;
  session: Session | null;
}

export function useSignUpWithoutPassword(supabase: SupabaseClient, api: AxiosInstance) {
  const [errors, setErrors] = useState<Record<string, string>>({});
  const { signUpToStream } = useSignUpToStream(api);
  const { mutateAsync, isPending } = useMutation<
    AuthResponse,
    { message: string; code: string },
    { email: string; name: string }
  >({
    mutationFn: async (data: { email: string; name: string }) => {
      // Generate a temporary password for the user
      const tempPassword =
        Math.random().toString(36).slice(-8) + Math.random().toString(36).slice(-8);

      const { data: response, error } = await supabase.auth.signUp({
        email: data.email.trim(),
        password: tempPassword,
        options: {
          data: {
            first_name: data.name.trim().split(" ")[0] || "",
            last_name: data.name.trim().split(" ").slice(1).join(" ") || "",
            business_name: "",
          },
        },
      });
      if (error) throw error;
      if (response.session?.access_token) {
        await signUpToStream(response.session.access_token);
      }

      // Mark the user as temporary
      if (response.session?.access_token) {
        await api.post(
          "/api/v1/users/mark-temporary",
          {
            temporary_password: tempPassword,
          },
          {
            headers: {
              Authorization: `Bearer ${response.session.access_token}`,
            },
          }
        );
      }
      return response;
    },
    onError: (error) => {
      const errMap: Record<string, string> = {};

      match(error.code)
        .with("user_already_exists", () => {
          errMap.email = "Cette adresse email est déjà utilisée";
        })
        .otherwise(() => {
          toast.add(
            {
              title: "Erreur",
              description: error.message,
              type: "error",
              position: "top-left",
            },
            {
              timeout: 5000,
            }
          );
        });

      setErrors(errMap);
    },
  });
  return { mutateAsync, isPending, errors };
}

export function useSignUpToStream(api: AxiosInstance) {
  const { mutate: signUpToStream } = useMutation({
    mutationFn: async (accessToken: string) => {
      const { data } = await api.post<{ streamToken: string }>(
        "/api/v1/users/sign-up-to-stream",
        {},
        {
          headers: {
            Authorization: `Bearer ${accessToken}`,
          },
        }
      );
      return data;
    },
  });
  return { signUpToStream };
}
