import {
  useQuery,
  useMutation,
  useQueryClient,
  useInfiniteQuery,
} from "@tanstack/react-query";
import { useAuthToken } from "../hooks/use-root-data";
import {
  SellerApplication,
  InstagramVerification,
} from "../../src/api/types/models";
import { toast } from "~/hooks/use-toast";
import { useNavigate } from "react-router-dom";
import {
  createFollowsManagementApi,
  createSellerManagementApi,
} from "~/utils/api-client-factory";
import { getApiBaseUrl } from "../utils/api-config";

// ── Multi-user team ─────────────────────────────────────────────────────────
export interface MyStore {
  username: string;
  storeName: string;
  storeLogo: string | null;
  role: "owner" | "staff" | null;
}

export interface StoreMember {
  id: string;
  userId: string | null;
  name: string | null;
  phone: string;
  role: string;
  status: "active" | "pending";
  createdAt: string;
}

/** Stores the current user can manage (owned + memberships), with their role. */
export function useMyStores() {
  const token = useAuthToken();
  return useQuery({
    queryKey: ["myStores", token ?? "anon"],
    queryFn: async (): Promise<MyStore[]> => {
      const res = await fetch(`${getApiBaseUrl()}/api/seller/v1/my-stores/`, {
        headers: { Authorization: `Bearer ${token}` },
      });
      // Throw on failure so a transient error stays an ERROR state (data kept,
      // retried) instead of resolving to [] — otherwise a blip would look like
      // "no stores" and bounce an owner off their own dashboard.
      if (!res.ok) throw new Error(`my-stores failed: ${res.status}`);
      return res.json();
    },
    enabled: !!token,
    retry: 1,
    staleTime: 60 * 1000,
  });
}

/** A store's team members (owner only). */
export function useStoreMembers(username?: string) {
  const token = useAuthToken();
  return useQuery({
    queryKey: ["storeMembers", username],
    queryFn: async (): Promise<StoreMember[]> => {
      const res = await fetch(
        `${getApiBaseUrl()}/api/seller/v1/members/${username}/`,
        { headers: { Authorization: `Bearer ${token}` } }
      );
      if (!res.ok) throw new Error("failed to load members");
      return res.json();
    },
    enabled: !!token && !!username,
  });
}

/** Invite a team member by phone number (owner only). */
export function useInviteMember(username?: string) {
  const token = useAuthToken();
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (phone: string) => {
      const res = await fetch(
        `${getApiBaseUrl()}/api/seller/v1/members/${username}/`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${token}`,
          },
          body: JSON.stringify({ phone }),
        }
      );
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new Error(err.error || "خطا در دعوت عضو جدید");
      }
      return res.json();
    },
    onSuccess: () =>
      queryClient.invalidateQueries({ queryKey: ["storeMembers", username] }),
  });
}

/** Remove a team member (owner only). */
export function useRemoveMember(username?: string) {
  const token = useAuthToken();
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (memberId: string) => {
      const res = await fetch(
        `${getApiBaseUrl()}/api/seller/v1/members/${username}/${memberId}/`,
        { method: "DELETE", headers: { Authorization: `Bearer ${token}` } }
      );
      if (!res.ok) throw new Error("خطا در حذف عضو");
      return res.json();
    },
    onSuccess: () =>
      queryClient.invalidateQueries({ queryKey: ["storeMembers", username] }),
  });
}

/**
 * Custom hook to fetch seller data by sellerId using React Query
 */
export const useSellerData = (sellerId: string | undefined) => {
  const token = useAuthToken();

  return useQuery({
    queryKey: ["seller", sellerId],
    queryFn: async () => {
      if (!sellerId) throw new Error("Seller ID is required");

      const sellerApi = createSellerManagementApi(token);
      return await sellerApi.sellerRead({ username: sellerId });
    },
    enabled: !!sellerId, // Only run the query if sellerId exists
  });
};

/**
 * Custom hook to check if the current user is following a seller
 */
export const useSellerFollowStatus = (sellerId: string | undefined) => {
  const token = useAuthToken();

  return useQuery({
    queryKey: ["sellerFollowStatus", sellerId],
    queryFn: async () => {
      if (!sellerId) throw new Error("Seller ID is required");
      if (!token) throw new Error("Authentication required");

      try {
        const followsApi = createFollowsManagementApi(token);
        const response = await followsApi.apiEngagementV1FollowsCheckRead({
          sellerId,
        });
        return response?.following;
      } catch (error) {
        return false; // If error is thrown, user is not following the seller
      }
    },
    enabled: !!sellerId && !!token, // Only run the query if sellerId and token exist
  });
};

/**
 * Custom hook to follow a seller
 */
export const useSellerFollow = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({ sellerId }: { sellerId: string }) => {
      if (!token) throw new Error("Authentication required");

      const followsApi = createFollowsManagementApi(token);
      await followsApi.apiEngagementV1FollowsCreate({
        data: { followingId: sellerId },
      });
      return { success: true };
    },
    onSuccess: (_, variables) => {
      // Invalidate and refetch follow status after mutation
      queryClient.invalidateQueries({
        queryKey: ["sellerFollowStatus", variables.sellerId],
      });
      queryClient.invalidateQueries({
        queryKey: ["getFollowedSellersService"],
      });
    },
  });
};

/**
 * Custom hook to unfollow a seller
 */
export const useSellerUnfollow = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({ sellerId }: { sellerId: string }) => {
      if (!token) throw new Error("Authentication required");

      const followsApi = createFollowsManagementApi(token);
      await followsApi.apiEngagementV1FollowsDelete({ sellerId });
      return { success: true };
    },
    onSuccess: (_, variables) => {
      // Invalidate and refetch follow status after mutation
      queryClient.invalidateQueries({
        queryKey: ["sellerFollowStatus", variables.sellerId],
      });
      queryClient.invalidateQueries({
        queryKey: ["getFollowedSellersService"],
      });
    },
  });
};

export const useGetSellerProducts = (
  sellerId: string,
  options?: {
    q?: string;
    priceMin?: number;
    priceMax?: number;
    ordering?: string;
  }
) => {
  const token = useAuthToken();
  return useInfiniteQuery({
    queryKey: ["sellerProducts", sellerId, options],
    queryFn: async ({ pageParam = 1 }) => {
      const sellerApi = createSellerManagementApi(token);
      return await sellerApi.sellerProductList({
        username: sellerId,
        page: pageParam,
        q: options?.q,
        priceMin: options?.priceMin,
        priceMax: options?.priceMax,
        ordering: options?.ordering,
      });
    },
    getNextPageParam: (lastPage) => {
      if (!lastPage.next) return undefined;
      // Extract page number from the next URL
      const url = new URL(lastPage.next);
      const page = url.searchParams.get("page");
      return page ? parseInt(page, 10) : undefined;
    },
    initialPageParam: 1,
    enabled: !!sellerId,
    // Public storefront: prices/discounts must reflect the seller's latest
    // edits. Always treat as stale and revalidate on mount/refocus so the
    // store list can't keep showing a pre-edit price (the detail page is SSR
    // and already fresh, which caused the list-vs-detail mismatch).
    staleTime: 0,
    refetchOnMount: true,
    refetchOnWindowFocus: true,
  });
};

/**
 * Custom hook to fetch seller categories
 */
export const useSellerCategories = () => {
  return useQuery({
    queryKey: ["sellerCategories"],
    queryFn: async () => {
      const sellerApi = createSellerManagementApi();
      return await sellerApi.apiSellerV1CategoriesList();
    },
  });
};

/**
 * Custom hook to fetch state and city data
 */
export const useStateCityData = () => {
  return useQuery({
    queryKey: ["stateCityData"],
    queryFn: async () => {
      const sellerApi = createSellerManagementApi();
      return await sellerApi.apiSellerV1StateCityList();
    },
  });
};

/**
 * Custom hook to create seller application
 */
export const useCreateSellerApplication = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (data: SellerApplication) => {
      if (!token) throw new Error("Authentication required");
      const sellerApi = createSellerManagementApi(token);
      return await sellerApi.apiSellerV1ApplyCreate({ data });
    },
    onSuccess: () => {
      // Invalidate profile query to refresh sellerUsername
      queryClient.invalidateQueries({ queryKey: ["getProfile"] });
    },
  });
};

/**
 * Custom hook to apply Instagram verification
 */
export const useInstagramVerification = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (
      data: InstagramVerification
    ): Promise<InstagramVerification> => {
      if (!token) throw new Error("Authentication required");

      const sellerApi = createSellerManagementApi(token);
      return await sellerApi.apiSellerV1InstapplyCreate({ data });
    },
    onSuccess: (data: InstagramVerification) => {
      if (data?.isVerified) {
        toast({
          title: "احراز اکانت اینستاگرام با موفقیت انجام شد",
          description: "اکانت اینستاگرام شما با موفقیت احراز شد",
        });
        // Invalidate seller data after successful verification
        queryClient.invalidateQueries({
          queryKey: ["seller"],
        });
      } else {
        toast({
          title: "احراز اکانت اینستاگرام با موفقیت انجام نشد",
          description: "لطفا مجددا تلاش کنید",
          variant: "destructive",
        });
      }
    },
    onError: () => {
      toast({
        title: "احراز اکانت اینستاگرام با موفقیت انجام نشد",
        description: "لطفا مجددا تلاش کنید",
        variant: "destructive",
      });
    },
  });
};

/**
 * Custom hook to update seller information
 */
export const useSellerUpdate = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();
  const navigate = useNavigate();
  return useMutation({
    mutationFn: async ({
      username,
      data,
    }: {
      username: string;
      data: {
        storeName: string;
        storeDescription?: string | null;
        storeLogo?: string | null;
        instagramId?: string | null;
        bannerType?: string | null;
        bannerColor?: string | null;
        bannerImage?: string | null;
      };
    }) => {
      if (!token) throw new Error("Authentication required");

      const sellerApi = createSellerManagementApi(token);
      return await sellerApi.sellerPartialUpdate({ username, data });
    },
    onSuccess: (_, variables) => {
      toast({
        title: "اطلاعات فروشگاه با موفقیت به‌روزرسانی شد",
        description: "تغییرات شما ذخیره شد",
      });
      // Invalidate seller data after successful update
      queryClient.invalidateQueries({
        queryKey: ["seller", variables.username],
      });
      navigate(`/store/${variables.username}`);
    },
    onError: () => {
      toast({
        title: "خطا در به‌روزرسانی اطلاعات",
        description: "لطفا مجددا تلاش کنید",
        variant: "destructive",
      });
    },
  });
};
