'use client';

import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import type { Session } from '@supabase/supabase-js';
import { supabase } from '../lib/supabase';
import { ACTIVE_TENANT_STORAGE_KEY, apiFetch, type MeResponse, type TenantMembership } from '../lib/api';

interface SessionContextValue {
  authSession: Session | null;
  authLoading: boolean;
  me: MeResponse | null;
  meLoading: boolean;
  activeTenant: TenantMembership | null;
  setActiveTenantId: (tenantId: string) => void;
  signOut: () => Promise<void>;
}

const SessionContext = createContext<SessionContextValue | null>(null);

export function SessionProvider({ children }: { children: React.ReactNode }) {
  const router = useRouter();
  const queryClient = useQueryClient();
  const [authSession, setAuthSession] = useState<Session | null>(null);
  const [authLoading, setAuthLoading] = useState(true);
  const [activeTenantId, setActiveTenantIdState] = useState<string | null>(null);

  useEffect(() => {
    supabase.auth.getSession().then(({ data }) => {
      setAuthSession(data.session);
      setAuthLoading(false);
    });
    const { data: subscription } = supabase.auth.onAuthStateChange((_event, session) => {
      setAuthSession(session);
    });
    setActiveTenantIdState(window.localStorage.getItem(ACTIVE_TENANT_STORAGE_KEY));
    return () => subscription.subscription.unsubscribe();
  }, []);

  const { data: me = null, isLoading: meLoading } = useQuery({
    queryKey: ['me', authSession?.user.id],
    queryFn: () => apiFetch<MeResponse>('/v1/me'),
    enabled: Boolean(authSession),
  });

  const activeTenant = useMemo(() => {
    if (!me || me.tenants.length === 0) {
      return null;
    }
    return me.tenants.find((tenant) => tenant.tenantId === activeTenantId) ?? me.tenants[0];
  }, [me, activeTenantId]);

  const setActiveTenantId = useCallback(
    (tenantId: string) => {
      window.localStorage.setItem(ACTIVE_TENANT_STORAGE_KEY, tenantId);
      setActiveTenantIdState(tenantId);
      // datele afisate apartin tenantului anterior — invalidam tot ce e tenant-scoped
      queryClient.invalidateQueries();
    },
    [queryClient],
  );

  const signOut = useCallback(async () => {
    await supabase.auth.signOut();
    window.localStorage.removeItem(ACTIVE_TENANT_STORAGE_KEY);
    queryClient.clear();
    router.push('/login');
  }, [queryClient, router]);

  const value = useMemo(
    () => ({ authSession, authLoading, me, meLoading, activeTenant, setActiveTenantId, signOut }),
    [authSession, authLoading, me, meLoading, activeTenant, setActiveTenantId, signOut],
  );

  return <SessionContext.Provider value={value}>{children}</SessionContext.Provider>;
}

export function useSession(): SessionContextValue {
  const context = useContext(SessionContext);
  if (!context) {
    throw new Error('useSession must be used inside SessionProvider');
  }
  return context;
}
