"use client";

import * as React from "react";
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";

export type UserRole = "admin" | "reviewer" | "viewer" | "editor" | "owner";

export type UserProfile = {
  displayName: string;
  email: string;
  jobTitle: string;
  company: string;
  bio: string;
  avatarUrl: string;
  hasPassword: boolean;
};

const DEFAULT_PROFILE: UserProfile = {
  displayName: "",
  email: "",
  jobTitle: "",
  company: "",
  bio: "",
  avatarUrl: "",
  hasPassword: false,
};

type UserProfileContextValue = {
  profile: UserProfile;
  updateProfile: (updates: Partial<UserProfile>) => Promise<void>;
  initials: string;
  userId?: string;
  role: UserRole;
  orgId?: string;
  orgName?: string;
  hasOrg: boolean;
  isAuthenticated: boolean;
  loading: boolean;
  switchOrg: (orgId: string) => Promise<void>;
};

const UserProfileContext = React.createContext<UserProfileContextValue | null>(null);

function getInitials(name: string): string {
  if (!name.trim()) return "";
  const parts = name.trim().split(/\s+/);
  if (parts.length === 1) return parts[0][0].toUpperCase();
  return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
}

export function UserProfileProvider({ children }: { children: React.ReactNode }) {
  const { data: session, status, update: updateSession } = useSession();
  const router = useRouter();
  const [dbProfile, setDbProfile] = React.useState<Partial<UserProfile>>({});
  const [mounted, setMounted] = React.useState(false);

  React.useEffect(() => {
    setMounted(true);
  }, []);

  React.useEffect(() => {
    if (status === "authenticated") {
      fetch("/api/auth/me")
        .then((r) => (r.ok ? r.json() : null))
        .then((data) => {
          if (data) {
            setDbProfile({
              displayName: data.displayName || "",
              email: data.email || "",
              avatarUrl: data.avatarUrl || "",
              jobTitle: data.jobTitle || "",
              company: data.company || "",
              bio: data.bio || "",
              hasPassword: data.hasPassword ?? false,
            });
          }
        })
        .catch(() => {});
    }
  }, [status]);

  const loading = status === "loading";
  const isAuthenticated = status === "authenticated";

  const profile = React.useMemo<UserProfile>(() => {
    const base: UserProfile = { ...DEFAULT_PROFILE };

    if (session?.user) {
      base.displayName = session.user.displayName || session.user.name || "";
      base.email = session.user.email || "";
      base.avatarUrl = session.user.avatarUrl || session.user.image || "";
    }

    return {
      ...base,
      ...dbProfile,
      ...(session?.user?.email ? { email: session.user.email } : {}),
    };
  }, [session, dbProfile]);

  const updateProfile = React.useCallback(async (updates: Partial<UserProfile>) => {
    setDbProfile((prev) => ({ ...prev, ...updates }));

    const apiPayload: Record<string, string> = {};
    const persistFields = ["displayName", "avatarUrl", "jobTitle", "company", "bio"] as const;
    for (const field of persistFields) {
      if (typeof updates[field] === "string") apiPayload[field] = updates[field];
    }

    if (Object.keys(apiPayload).length > 0) {
      try {
        await fetch("/api/auth/me", {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(apiPayload),
        });
      } catch {}
    }
  }, []);

  const initials = React.useMemo(() => getInitials(profile.displayName), [profile.displayName]);

  const userId = session?.user?.id;
  const role: UserRole = (session?.user?.role as UserRole) ?? "viewer";
  const orgId = session?.user?.orgId;
  const orgName = session?.user?.orgName;
  const hasOrg = session?.user?.hasOrg ?? false;

  const switchOrg = React.useCallback(
    async (targetOrgId: string) => {
      await fetch("/api/org/switch", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ orgId: targetOrgId }),
      });
      await updateSession();
      router.refresh();
    },
    [updateSession, router]
  );

  const value = React.useMemo(
    () => ({ profile, updateProfile, initials, userId, role, orgId, orgName, hasOrg, isAuthenticated, loading, switchOrg }),
    [profile, updateProfile, initials, userId, role, orgId, orgName, hasOrg, isAuthenticated, loading, switchOrg]
  );

  if (!mounted) return <>{children}</>;

  return (
    <UserProfileContext.Provider value={value}>
      {children}
    </UserProfileContext.Provider>
  );
}

export function useUserProfile() {
  const ctx = React.useContext(UserProfileContext);
  if (!ctx) {
    return {
      profile: { ...DEFAULT_PROFILE },
      updateProfile: async () => {},
      initials: "",
      userId: undefined,
      role: "viewer" as UserRole,
      orgId: undefined,
      orgName: undefined,
      hasOrg: false,
      isAuthenticated: false,
      loading: false,
      switchOrg: async () => {},
    };
  }
  return ctx;
}
