// ============================================================
// AgenticX — Área do Cliente · autenticação e infraestrutura
// Rotas hash: #cliente/login · #cliente/esqueci · #cliente/redefinir
// PRD: PRD_AREA_CLIENTE.md
// ============================================================

// Producao: API em subdominio dedicado (api-landing.agenticx.com.br), separado
// do frontend (agenticx.com.br / landing.agenticx.com.br) -- exige CORS +
// credentials:'include' (ver api/app/main.py). Dev local: mesma origem via
// proxy do _serve.js, sem CORS.
const API_BASE = (() => {
  const host = window.location.hostname;
  if (host === 'localhost' || host === '127.0.0.1') return '/api';
  return 'https://api-landing.agenticx.com.br/api';
})();

async function apiFetch(path, options = {}) {
  const res = await fetch(`${API_BASE}${path}`, {
    method: options.method || 'GET',
    credentials: 'include',
    headers: options.body ? { 'Content-Type': 'application/json' } : undefined,
    body: options.body ? JSON.stringify(options.body) : undefined,
  });

  let data = null;
  const text = await res.text();
  if (text) {
    try { data = JSON.parse(text); } catch (e) { /* resposta sem corpo JSON */ }
  }

  if (!res.ok) {
    const err = new Error((data && data.detail) || `Erro ${res.status}`);
    err.status = res.status;
    err.data = data;
    throw err;
  }
  return data;
}

// '#cliente/redefinir?token=abc' -> { sub: 'redefinir', token: 'abc' }
function parseClienteRoute(hash) {
  const raw = (hash || '').replace('#', '');
  const [pathPart, queryPart] = raw.split('?');
  const sub = pathPart.split('/')[1] || '';
  const params = new URLSearchParams(queryPart || '');
  return { sub, token: params.get('token') };
}

// status: 'loading' | 'anon' | 'authed'
function useAuth() {
  const [state, setState] = React.useState({ status: 'loading', user: null });

  const refresh = React.useCallback(async () => {
    try {
      const user = await apiFetch('/me');
      setState({ status: 'authed', user });
    } catch (err) {
      setState({ status: 'anon', user: null });
    }
  }, []);

  React.useEffect(() => { refresh(); }, [refresh]);

  const login = React.useCallback(async (email, senha) => {
    await apiFetch('/auth/login', { method: 'POST', body: { email, senha } });
    await refresh();
  }, [refresh]);

  const logout = React.useCallback(async () => {
    try { await apiFetch('/auth/logout', { method: 'POST' }); } catch (err) { /* sessao ja invalida */ }
    // Navega ANTES de marcar 'anon': window.location.hash atualiza de forma sincrona
    // (o evento 'hashchange' e assincrono), entao o guard de rota do ClienteRouter,
    // que le o hash ao vivo, ja enxerga a home e nao forca redirect para o login.
    window.location.hash = '#';
    setState({ status: 'anon', user: null });
  }, []);

  return { ...state, login, logout, refresh };
}

// ---------- Shell visual comum das telas de autenticação ----------
const ClienteAuthShell = ({ eyebrow, title, subtitle, children }) => (
  <section className="min-h-[70vh] flex items-center justify-center bg-[#FAFAF8] py-16 px-6">
    <div className="w-full max-w-md bg-white rounded-2xl border border-line p-8 sm:p-10">
      <Eyebrow>{eyebrow}</Eyebrow>
      <h1 className="mt-4 text-2xl sm:text-3xl font-medium text-black leading-tight">{title}</h1>
      {subtitle && <p className="mt-2 text-sm text-slate">{subtitle}</p>}
      <div className="mt-8">{children}</div>
    </div>
  </section>
);

const ClienteLoadingScreen = () => (
  <section className="min-h-[70vh] flex items-center justify-center bg-[#FAFAF8]">
    <div className="w-10 h-10 rounded-full border-2 border-line border-t-forest animate-spin" aria-label="Carregando"></div>
  </section>
);

const clienteInputCls = "w-full rounded-xl bg-white ring-1 ring-line px-4 py-3 text-sm text-black placeholder:text-slate/60 focus:outline-none focus:ring-forest";

// ---------- Login ----------
const ClienteLogin = ({ auth }) => {
  const [email, setEmail] = React.useState('');
  const [senha, setSenha] = React.useState('');
  const [error, setError] = React.useState('');
  const [loading, setLoading] = React.useState(false);

  const handleSubmit = async (e) => {
    e.preventDefault();
    setError('');
    setLoading(true);
    try {
      await auth.login(email, senha);
      window.location.hash = '#cliente';
    } catch (err) {
      setError(err.status === 429 ? 'Muitas tentativas. Tente novamente mais tarde.' : 'E-mail ou senha inválidos.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <ClienteAuthShell
      eyebrow="Área do cliente"
      title={<>Acesse sua <span className="font-em text-forest">conta</span></>}
      subtitle="Entre com seu e-mail e senha para consultar seus dados."
    >
      <form onSubmit={handleSubmit} className="space-y-5">
        <label className="block">
          <span className="block text-xs font-medium text-slate mb-2">E-mail</span>
          <input type="email" required autoFocus value={email} onChange={(e) => setEmail(e.target.value)}
            className={clienteInputCls} placeholder="voce@empresa.com"/>
        </label>
        <label className="block">
          <span className="block text-xs font-medium text-slate mb-2">Senha</span>
          <input type="password" required value={senha} onChange={(e) => setSenha(e.target.value)}
            className={clienteInputCls} placeholder="••••••••"/>
        </label>
        {error && <p className="text-sm text-red-700">{error}</p>}
        <SlideButton as="button" type="submit" variant="forest" className="w-full justify-center" disabled={loading}>
          {loading ? 'Entrando…' : 'Entrar'}
        </SlideButton>
        <div className="text-center">
          <a href="#cliente/esqueci" className="text-xs font-medium text-forest hover:text-forest-700 underline underline-offset-4">
            Esqueci minha senha
          </a>
        </div>
      </form>
    </ClienteAuthShell>
  );
};

// ---------- Esqueci minha senha ----------
const ClienteEsqueciSenha = () => {
  const [email, setEmail] = React.useState('');
  const [enviado, setEnviado] = React.useState(false);
  const [loading, setLoading] = React.useState(false);

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    try {
      await apiFetch('/auth/forgot-password', { method: 'POST', body: { email } });
    } catch (err) {
      // Resposta sempre generica (RF-13): nao expor se o e-mail existe ou nao.
    } finally {
      setLoading(false);
      setEnviado(true);
    }
  };

  return (
    <ClienteAuthShell
      eyebrow="Área do cliente"
      title={<>Esqueceu sua <span className="font-em text-forest">senha</span>?</>}
      subtitle="Informe seu e-mail cadastrado para receber instruções de redefinição."
    >
      {enviado ? (
        <div className="p-6 bg-forest/5 border border-forest/10 rounded-2xl text-center">
          <div className="w-12 h-12 rounded-full bg-forest text-white flex items-center justify-center mx-auto mb-4">
            <ICheck size={24}/>
          </div>
          <p className="text-sm text-slate">
            Se o e-mail informado existir em nossa base, você receberá instruções para redefinir sua senha em instantes.
          </p>
        </div>
      ) : (
        <form onSubmit={handleSubmit} className="space-y-5">
          <label className="block">
            <span className="block text-xs font-medium text-slate mb-2">E-mail</span>
            <input type="email" required autoFocus value={email} onChange={(e) => setEmail(e.target.value)}
              className={clienteInputCls} placeholder="voce@empresa.com"/>
          </label>
          <SlideButton as="button" type="submit" variant="forest" className="w-full justify-center" disabled={loading}>
            {loading ? 'Enviando…' : 'Enviar instruções'}
          </SlideButton>
        </form>
      )}
      <div className="mt-6 text-center">
        <a href="#cliente/login" className="text-xs font-medium text-forest hover:text-forest-700 underline underline-offset-4">
          Voltar ao login
        </a>
      </div>
    </ClienteAuthShell>
  );
};

// ---------- Redefinir senha ----------
const ClienteRedefinirSenha = ({ token }) => {
  const [novaSenha, setNovaSenha] = React.useState('');
  const [confirmacao, setConfirmacao] = React.useState('');
  const [error, setError] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [sucesso, setSucesso] = React.useState(false);

  const handleSubmit = async (e) => {
    e.preventDefault();
    setError('');
    if (novaSenha.length < 10) { setError('A senha deve ter no mínimo 10 caracteres.'); return; }
    if (novaSenha !== confirmacao) { setError('As senhas não coincidem.'); return; }
    setLoading(true);
    try {
      await apiFetch('/auth/reset-password', { method: 'POST', body: { token, nova_senha: novaSenha } });
      setSucesso(true);
    } catch (err) {
      setError(err.status === 400 ? 'Link inválido ou expirado. Solicite uma nova redefinição.' : 'Não foi possível redefinir sua senha.');
    } finally {
      setLoading(false);
    }
  };

  if (!token) {
    return (
      <ClienteAuthShell eyebrow="Área do cliente" title="Link inválido">
        <p className="text-sm text-slate">
          Este link de redefinição de senha é inválido ou incompleto. Solicite um novo em{' '}
          <a href="#cliente/esqueci" className="text-forest underline underline-offset-4">esqueci minha senha</a>.
        </p>
      </ClienteAuthShell>
    );
  }

  if (sucesso) {
    return (
      <ClienteAuthShell eyebrow="Área do cliente" title="Senha redefinida">
        <div className="p-6 bg-forest/5 border border-forest/10 rounded-2xl text-center">
          <div className="w-12 h-12 rounded-full bg-forest text-white flex items-center justify-center mx-auto mb-4">
            <ICheck size={24}/>
          </div>
          <p className="text-sm text-slate mb-4">Sua senha foi redefinida com sucesso.</p>
          <a href="#cliente/login" className="text-xs font-semibold text-forest underline underline-offset-4 hover:text-forest-700">
            Ir para o login
          </a>
        </div>
      </ClienteAuthShell>
    );
  }

  return (
    <ClienteAuthShell
      eyebrow="Área do cliente"
      title={<>Defina uma nova <span className="font-em text-forest">senha</span></>}
      subtitle="Mínimo de 10 caracteres."
    >
      <form onSubmit={handleSubmit} className="space-y-5">
        <label className="block">
          <span className="block text-xs font-medium text-slate mb-2">Nova senha</span>
          <input type="password" required minLength={10} value={novaSenha} onChange={(e) => setNovaSenha(e.target.value)}
            className={clienteInputCls}/>
        </label>
        <label className="block">
          <span className="block text-xs font-medium text-slate mb-2">Confirmar nova senha</span>
          <input type="password" required minLength={10} value={confirmacao} onChange={(e) => setConfirmacao(e.target.value)}
            className={clienteInputCls}/>
        </label>
        {error && <p className="text-sm text-red-700">{error}</p>}
        <SlideButton as="button" type="submit" variant="forest" className="w-full justify-center" disabled={loading}>
          {loading ? 'Salvando…' : 'Redefinir senha'}
        </SlideButton>
      </form>
    </ClienteAuthShell>
  );
};

// ---------- Router da área do cliente (delega o dashboard a cliente-paginas.jsx) ----------
const ClienteRouter = ({ hash, auth }) => {
  const { sub, token } = parseClienteRoute(hash);
  const isAuthRoute = sub === 'login' || sub === 'esqueci' || sub === 'redefinir';

  React.useEffect(() => {
    if (auth.status === 'loading') return;
    // Le o hash AO VIVO (nao a prop, que pode estar um render atrasada) para nao
    // reagir a um estado intermediario ja obsoleto — ex.: logout() troca o hash
    // para fora de #cliente antes de marcar auth 'anon'; sem essa checagem, este
    // efeito re-redirecionaria para o login por engano.
    const liveSub = parseClienteRoute(window.location.hash).sub;
    if (liveSub === 'login' && auth.status === 'authed') {
      window.location.hash = '#cliente';
    } else if (!isAuthRoute && auth.status === 'anon' && liveSub === sub) {
      window.location.hash = '#cliente/login';
    }
  }, [sub, isAuthRoute, auth.status]);

  if (auth.status === 'loading') return <ClienteLoadingScreen/>;

  if (sub === 'login') return auth.status === 'authed' ? <ClienteLoadingScreen/> : <ClienteLogin auth={auth}/>;
  if (sub === 'esqueci') return <ClienteEsqueciSenha/>;
  if (sub === 'redefinir') return <ClienteRedefinirSenha token={token}/>;

  return auth.status === 'authed' ? <ClienteDashboard auth={auth}/> : <ClienteLoadingScreen/>;
};

Object.assign(window, {
  apiFetch, parseClienteRoute, useAuth,
  ClienteAuthShell, ClienteLoadingScreen,
  ClienteLogin, ClienteEsqueciSenha, ClienteRedefinirSenha, ClienteRouter,
});
