'use client';

import { useCallback, useEffect, useState } from 'react';

export interface StoreCliente {
  id: string;
  empresa_id: string;
  email: string;
  nombre: string;
  telefono?: string;
  documento?: string;
}

interface AuthState {
  cliente: StoreCliente | null;
  token: string | null;
}

interface CartItem {
  id: string;
  quantity: number;
  name: string;
  price: number;
  image: string;
}

const STORAGE_KEY = 'store_auth';

function readStorage(): AuthState {
  try {
    const raw = typeof window !== 'undefined' ? localStorage.getItem(STORAGE_KEY) : null;
    return raw ? (JSON.parse(raw) as AuthState) : { cliente: null, token: null };
  } catch {
    return { cliente: null, token: null };
  }
}

export function useStoreAuth(subdominio: string) {
  const [state, setState] = useState<AuthState>({ cliente: null, token: null });
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const persist = useCallback((next: AuthState) => {
    try { localStorage.setItem(STORAGE_KEY, JSON.stringify(next)); } catch { /* noop */ }
    setState(next);
  }, []);

  const headers = useCallback(
    (withAuth = false) => ({
      'Content-Type': 'application/json',
      ...(withAuth && state.token ? { Authorization: `Bearer ${state.token}` } : {}),
    }),
    [state.token],
  );

  const login = useCallback(
    async (email: string, password: string) => {
      setLoading(true);
      setError(null);
      try {
        const res = await fetch('/api/store/auth/login', {
          method: 'POST',
          headers: headers(),
          body: JSON.stringify({ email, password, subdominio }),
        });
        if (!res.ok) {
          const body = await res.json().catch(() => ({}));
          throw new Error(body?.message ?? 'Credenciales incorrectas');
        }
        const data = (await res.json()) as { access_token: string; cliente: StoreCliente };
        persist({ cliente: data.cliente, token: data.access_token });
        return data.cliente;
      } catch (e: unknown) {
        const msg = e instanceof Error ? e.message : 'Error al iniciar sesión';
        setError(msg);
        throw e;
      } finally {
        setLoading(false);
      }
    },
    [subdominio, headers, persist],
  );

  const register = useCallback(
    async (payload: { email: string; password: string; nombre: string; telefono?: string; documento?: string }) => {
      setLoading(true);
      setError(null);
      try {
        const res = await fetch('/api/store/auth/register', {
          method: 'POST',
          headers: headers(),
          body: JSON.stringify({ ...payload, subdominio }),
        });
        if (!res.ok) {
          const body = await res.json().catch(() => ({}));
          throw new Error(body?.message ?? 'Error al registrarse');
        }
        const data = (await res.json()) as { access_token: string; cliente: StoreCliente };
        persist({ cliente: data.cliente, token: data.access_token });
        return data.cliente;
      } catch (e: unknown) {
        const msg = e instanceof Error ? e.message : 'Error al registrarse';
        setError(msg);
        throw e;
      } finally {
        setLoading(false);
      }
    },
    [subdominio, headers, persist],
  );

  const logout = useCallback(() => {
    try { localStorage.removeItem(STORAGE_KEY); } catch { /* noop */ }
    setState({ cliente: null, token: null });
  }, []);

  // Sincroniza el carrito local → BD al iniciar sesión.
  const syncCart = useCallback(
    async (items: CartItem[]) => {
      if (!state.token || items.length === 0) return;
      try {
        await fetch('/api/store/auth/cart/sync', {
          method: 'POST',
          headers: headers(true),
          body: JSON.stringify({ subdominio, items }),
        });
      } catch { /* silencioso — el carrito local es la fuente de verdad */ }
    },
    [subdominio, state.token, headers],
  );

  // Hidrata la sesión después del primer render para mantener estable el HTML SSR.
  useEffect(() => {
    const stored = readStorage();

    setState(stored);
    if (!stored.token) return;

    fetch('/api/store/auth/me', {
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${stored.token}`,
      },
    })
      .then((r) => (r.ok ? r.json() : null))
      .then((data: StoreCliente | null) => {
        if (data) persist({ ...stored, cliente: data });
        else persist({ cliente: null, token: null });
      })
      .catch(() => { /* sin red — mantener estado local */ });
  }, [persist, subdominio]);

  const updateProfile = useCallback(
    async (data: { nombre?: string; telefono?: string }) => {
      if (!state.token) throw new Error('No autenticado');
      setLoading(true);
      setError(null);
      try {
        const res = await fetch('/api/store/auth/me', {
          method: 'PUT',
          headers: headers(true),
          body: JSON.stringify(data),
        });
        if (!res.ok) {
          const body = await res.json().catch(() => ({}));
          throw new Error(body?.message ?? 'Error al actualizar perfil');
        }
        const updated = (await res.json()) as Partial<StoreCliente>;
        persist({ ...state, cliente: state.cliente ? { ...state.cliente, ...updated } : state.cliente });
      } catch (e: unknown) {
        const msg = e instanceof Error ? e.message : 'Error al actualizar';
        setError(msg);
        throw e;
      } finally {
        setLoading(false);
      }
    },
    [state, headers, persist],
  );

  return {
    cliente: state.cliente,
    token: state.token,
    isLoggedIn: !!state.cliente,
    loading,
    error,
    login,
    register,
    logout,
    syncCart,
    updateProfile,
    clearError: () => setError(null),
  };
}
