// Copyright: © 2026 TWWIM UG. All rights reserved. (www.twwim.com)
/**
 * AcceptInvitationPage — landing page hit from the INVITATION_MEMBER email.
 *
 * Reads the `token` query param, prompts the invitee for a password
 * (optionally first/last name on a fresh account), POSTs to
 * /auth/accept-invitation, then immediately logs them in and routes to
 * their role's landing zone (OPERATOR → /dashboard/conversations,
 * ADMIN → /dashboard).
 */

import { useState } from 'react';
import { useNavigate } from '@tanstack/react-router';
import { Mail, KeyRound } from 'lucide-react';
import { ACCEPT_INVITATION, LOGIN } from '@archer/api-interface/endpoints/customer-api';
import type { AcceptInvitationRequest, TokenResponse } from '@archer/api-interface';
import { apiClient } from '@/infrastructure/http/ApiClient';
import { AuthenticatedUserMapper } from '@/infrastructure/http/api/auth/mappers/AuthenticatedUserMapper';
import { authenticatedUserStore } from '@/infrastructure/storage/AuthenticatedUserStore';
import { tokenStorage } from '@/infrastructure/storage/LocalTokenStorage';
import { useTranslation } from '@/i18n/TranslationProvider';

interface AcceptInvitationPageProps {
  token: string;
  email?: string;
}

export function AcceptInvitationPage({ token, email: hintedEmail }: AcceptInvitationPageProps) {
  const { t } = useTranslation();
  const navigate = useNavigate();

  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [password, setPassword] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleSubmit = async (event: React.FormEvent) => {
    event.preventDefault();
    setError(null);
    setSubmitting(true);
    try {
      const acceptBody: AcceptInvitationRequest = {
        token,
        password,
        firstName: firstName.trim() || undefined,
        lastName: lastName.trim() || undefined,
      };
      const accepted = await apiClient.post<{ success: true; authId: string; message: string }>(
        ACCEPT_INVITATION.path,
        acceptBody,
      );
      if (!accepted.success) {
        throw new Error(t('acceptInvitation.rejected'));
      }

      // Auto-login after a successful accept so the invitee lands on their
      // dashboard directly instead of bouncing back to /login.
      const loginEmail = hintedEmail ?? promptForEmail(t);
      const loginResponse = await apiClient.post<TokenResponse>(LOGIN.path, {
        email: loginEmail,
        password,
      });
      tokenStorage.setTokens(loginResponse.accessToken, loginResponse.refreshToken);
      const user = AuthenticatedUserMapper.fromTokenResponse(loginResponse);
      authenticatedUserStore.set(user);

      navigate({ to: '/dashboard' });
    } catch (err) {
      setError(err instanceof Error ? err.message : t('acceptInvitation.failed'));
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="min-h-screen flex items-center justify-center bg-slate-50 px-4">
      <div className="w-full max-w-md bg-white border border-gray-200 rounded-lg shadow-sm p-8" data-testid="accept-invitation-page">
        <div className="flex items-center gap-2 text-emerald-600 mb-3">
          <Mail size={20} />
          <span className="text-sm font-medium">{t('acceptInvitation.badge')}</span>
        </div>
        <h1 className="text-2xl font-semibold mb-1">{t('acceptInvitation.title')}</h1>
        <p className="text-sm text-gray-500 mb-6">{t('acceptInvitation.subtitle')}</p>

        {error && (
          <div className="rounded-md bg-red-50 border border-red-200 p-3 text-sm text-red-700 mb-4" data-testid="accept-invitation-error">
            {error}
          </div>
        )}

        <form onSubmit={handleSubmit} className="space-y-3">
          <div className="grid grid-cols-2 gap-3">
            <input
              type="text"
              placeholder={t('acceptInvitation.firstName')}
              value={firstName}
              onChange={(event) => setFirstName(event.target.value)}
              data-testid="accept-firstname"
              className="border border-gray-300 rounded-md px-3 py-2 text-sm"
            />
            <input
              type="text"
              placeholder={t('acceptInvitation.lastName')}
              value={lastName}
              onChange={(event) => setLastName(event.target.value)}
              data-testid="accept-lastname"
              className="border border-gray-300 rounded-md px-3 py-2 text-sm"
            />
          </div>
          <input
            type="password"
            placeholder={t('acceptInvitation.password')}
            value={password}
            onChange={(event) => setPassword(event.target.value)}
            required
            minLength={12}
            data-testid="accept-password"
            className="w-full border border-gray-300 rounded-md px-3 py-2 text-sm"
          />
          <button
            type="submit"
            disabled={submitting || password.length < 12}
            data-testid="accept-submit"
            className="w-full bg-emerald-600 hover:bg-emerald-700 text-white font-medium rounded-md px-4 py-2 text-sm disabled:opacity-50 inline-flex items-center justify-center gap-2"
          >
            <KeyRound size={16} />
            {submitting ? t('acceptInvitation.submitting') : t('acceptInvitation.submit')}
          </button>
        </form>
      </div>
    </div>
  );
}

function promptForEmail(t: (key: string) => string): string {
  const entered = typeof window !== 'undefined' ? window.prompt(t('acceptInvitation.emailPrompt')) : null;
  if (!entered) throw new Error(t('acceptInvitation.emailRequired'));
  return entered.trim();
}
