﻿/* global React, firebase, getKitchenAuth, getKitchenDb, usernameToEmail, USER_ROLES, ROLE_ORDER, ACCOUNT_STATUS, STORES, DEFAULT_STORE, normalizeRole, roleLabel */
const {
  useEffect: useEffectAuth,
  useMemo: useMemoAuth,
  useState: useStateAuth,
} = React;

function displayInitials(nameOrEmail) {
  const parts = String(nameOrEmail || '').trim().split(/\s+/).filter(Boolean);
  if (!parts.length) return 'KF';
  return parts.slice(0, 2).map((p) => p[0]).join('').toUpperCase();
}

function firstNameLabel(fullName) {
  return String(fullName || 'Team member').trim().split(/\s+/)[0] || 'Team member';
}

function normalizeAccountStatus(status) {
  const normalized = String(status || '').trim().toLowerCase();
  if (normalized === ACCOUNT_STATUS.APPROVED) return ACCOUNT_STATUS.APPROVED;
  if (normalized === ACCOUNT_STATUS.REJECTED) return ACCOUNT_STATUS.REJECTED;
  if (normalized === ACCOUNT_STATUS.DISABLED) return ACCOUNT_STATUS.DISABLED;
  return ACCOUNT_STATUS.PENDING;
}

function authErrorMessage(error) {
  const code = error?.code || '';
  if (code === 'permission-denied') {
    return 'Account setup is missing permission for this action. Ask an admin to check access rules.';
  }
  if (code === 'auth/configuration-not-found') {
    return 'Login is not configured for this site. Ask an admin to enable username and password sign-in.';
  }
  if (code === 'auth/operation-not-allowed') {
    return 'Username and password login is currently disabled.';
  }
  if (code === 'auth/invalid-credential' || code === 'auth/wrong-password' || code === 'auth/user-not-found') {
    return 'Invalid username/email or password.';
  }
  if (code === 'auth/email-already-in-use') {
    return 'This username/email already has an account. Try logging in or use another username.';
  }
  if (code === 'auth/weak-password') {
    return 'Password is too weak. Use at least 6 characters.';
  }
  if (code === 'auth/unauthorized-domain') {
    return 'This website domain is not authorized for staff login.';
  }
  return error?.message || 'Login failed.';
}

function greetingForNow() {
  const h = new Date().getHours();
  if (h < 12) return 'Good morning';
  if (h < 17) return 'Good afternoon';
  return 'Good evening';
}

function cleanProfile(uid, data, user) {
  const store = STORES.find((s) => s.storeId === data?.storeId) || DEFAULT_STORE;
  return {
    uid,
    email: data?.email || user?.email || '',
    username: data?.username || String(user?.email || '').split('@')[0] || '',
    fullName: data?.fullName || user?.displayName || 'Pending user',
    role: normalizeRole(data?.role || data?.requestedRole || USER_ROLES.STAFF),
    requestedRole: normalizeRole(data?.requestedRole || data?.role || USER_ROLES.STAFF),
    status: normalizeAccountStatus(data?.status),
    storeId: store.storeId,
    storeName: data?.storeName || store.displayName,
    createdAt: data?.createdAt || null,
    updatedAt: data?.updatedAt || null,
  };
}

async function fetchOrCreateUserProfile(user) {
  const db = getKitchenDb();
  const ref = db.collection('users').doc(user.uid);
  const snap = await ref.get();
  if (snap.exists) return cleanProfile(user.uid, snap.data(), user);

  const fallback = {
    uid: user.uid,
    email: user.email || '',
    username: String(user.email || '').split('@')[0] || '',
    fullName: user.displayName || 'Pending user',
    requestedRole: USER_ROLES.STAFF,
    role: USER_ROLES.STAFF,
    status: ACCOUNT_STATUS.PENDING,
    storeId: DEFAULT_STORE.storeId,
    storeName: DEFAULT_STORE.displayName,
    createdAt: firebase.firestore.FieldValue.serverTimestamp(),
    updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
  };
  await ref.set(fallback, { merge: true });
  return cleanProfile(user.uid, fallback, user);
}

function AuthShell({ title, subtitle, children }) {
  return (
    <div className="auth-screen">
      <div className="auth-card">
        <div className="auth-brand">
          <img src="../logos/logos_kfc-white.png" alt="KFC" />
          <div>
            <strong>Ar<span>Dh</span></strong>
            <small>Kitchen Intelligence</small>
          </div>
        </div>
        <h1>{title}</h1>
        {subtitle && <p>{subtitle}</p>}
        {children}
      </div>
    </div>
  );
}

function LoginForm({ onMode }) {
  const [form, setForm] = useStateAuth({ username: '', password: '' });
  const [busy, setBusy] = useStateAuth(false);
  const [error, setError] = useStateAuth('');

  const submit = async (event) => {
    event.preventDefault();
    setBusy(true);
    setError('');
    try {
      await getKitchenAuth().signInWithEmailAndPassword(usernameToEmail(form.username), form.password);
    } catch (err) {
      setError(authErrorMessage(err));
    } finally {
      setBusy(false);
    }
  };

  return (
    <AuthShell title="Sign in" subtitle="Use your approved Kitchen Intelligence account.">
      <form className="auth-form" onSubmit={submit}>
        <label>Username or email<input value={form.username} onChange={(e) => setForm((v) => Object.assign({}, v, { username: e.target.value }))} autoComplete="username" /></label>
        <label>Password<input type="password" value={form.password} onChange={(e) => setForm((v) => Object.assign({}, v, { password: e.target.value }))} autoComplete="current-password" /></label>
        {error && <div className="auth-alert error">{error}</div>}
        <button className="auth-primary" disabled={busy}>{busy ? 'Signing in...' : 'Login'}</button>
      </form>
      <button className="auth-link" onClick={() => onMode('signup')}>Request a new account</button>
    </AuthShell>
  );
}

function SignupForm({ onMode }) {
  const [form, setForm] = useStateAuth({
    fullName: '',
    username: '',
    requestedRole: USER_ROLES.STAFF,
    storeId: DEFAULT_STORE.storeId,
    password: '',
    confirmPassword: '',
  });
  const [busy, setBusy] = useStateAuth(false);
  const [error, setError] = useStateAuth('');

  const submit = async (event) => {
    event.preventDefault();
    setBusy(true);
    setError('');
    try {
      if (!form.fullName.trim()) throw new Error('Full name is required.');
      if (!form.username.trim()) throw new Error('Username or email is required.');
      if (form.password.length < 6) throw new Error('Password must be at least 6 characters.');
      if (form.password !== form.confirmPassword) throw new Error('Passwords do not match.');
      const store = STORES.find((s) => s.storeId === form.storeId) || DEFAULT_STORE;
      const email = usernameToEmail(form.username);
      const cred = await getKitchenAuth().createUserWithEmailAndPassword(email, form.password);
      await cred.user.updateProfile({ displayName: form.fullName.trim() });
      await getKitchenDb().collection('users').doc(cred.user.uid).set({
        uid: cred.user.uid,
        email,
        username: String(form.username).trim().toLowerCase(),
        fullName: form.fullName.trim(),
        requestedRole: normalizeRole(form.requestedRole),
        role: normalizeRole(form.requestedRole),
        status: ACCOUNT_STATUS.PENDING,
        storeId: store.storeId,
        storeName: store.displayName,
        createdAt: firebase.firestore.FieldValue.serverTimestamp(),
        updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
      });
    } catch (err) {
      setError(authErrorMessage(err));
    } finally {
      setBusy(false);
    }
  };

  return (
    <AuthShell title="Request account" subtitle="New users wait for admin approval before accessing operations.">
      <form className="auth-form" onSubmit={submit}>
        <label>Full name<input value={form.fullName} onChange={(e) => setForm((v) => Object.assign({}, v, { fullName: e.target.value }))} /></label>
        <label>Username or email<input value={form.username} onChange={(e) => setForm((v) => Object.assign({}, v, { username: e.target.value }))} autoComplete="username" /></label>
        <label>Requested role<select value={form.requestedRole} onChange={(e) => setForm((v) => Object.assign({}, v, { requestedRole: e.target.value }))}>{ROLE_ORDER.filter((r) => r !== USER_ROLES.ADMIN).map((role) => <option key={role} value={role}>{roleLabel(role)}</option>)}</select></label>
        <label>Location<select value={form.storeId} onChange={(e) => setForm((v) => Object.assign({}, v, { storeId: e.target.value }))}>{STORES.map((store) => <option key={store.storeId} value={store.storeId}>{store.displayName}</option>)}</select></label>
        <label>Password<input type="password" value={form.password} onChange={(e) => setForm((v) => Object.assign({}, v, { password: e.target.value }))} autoComplete="new-password" /></label>
        <label>Confirm password<input type="password" value={form.confirmPassword} onChange={(e) => setForm((v) => Object.assign({}, v, { confirmPassword: e.target.value }))} autoComplete="new-password" /></label>
        {error && <div className="auth-alert error">{error}</div>}
        <button className="auth-primary" disabled={busy}>{busy ? 'Submitting...' : 'Submit for approval'}</button>
      </form>
      <button className="auth-link" onClick={() => onMode('login')}>Back to login</button>
    </AuthShell>
  );
}

function PendingApproval({ profile, onSignOut }) {
  return (
    <AuthShell title="Waiting for admin approval" subtitle="Your account request has been received.">
      <div className="auth-status-card">
        <span className="material-symbols-rounded">hourglass_top</span>
        <strong>{profile?.fullName || 'Pending user'}</strong>
        <p>{profile?.storeName || DEFAULT_STORE.displayName} · {roleLabel(profile?.requestedRole || profile?.role)}</p>
        <small>An admin must approve this account before the main app opens.</small>
      </div>
      <button className="auth-secondary" onClick={onSignOut}>Sign out</button>
    </AuthShell>
  );
}

function BlockedAccount({ profile, onSignOut }) {
  const disabled = profile?.status === ACCOUNT_STATUS.DISABLED;
  return (
    <AuthShell title={disabled ? 'Account disabled' : 'Account not approved'} subtitle="Access to Kitchen Intelligence is blocked.">
      <div className="auth-alert error">Status: {profile?.status || 'unknown'}</div>
      <button className="auth-secondary" onClick={onSignOut}>Sign out</button>
    </AuthShell>
  );
}

function AuthGate({ children }) {
  const [mode, setMode] = useStateAuth('login');
  const [state, setState] = useStateAuth({ loading: true, user: null, profile: null, error: '' });

  useEffectAuth(() => {
    let cancelled = false;
    const unsub = getKitchenAuth().onAuthStateChanged(async (user) => {
      if (!user) {
        if (!cancelled) setState({ loading: false, user: null, profile: null, error: '' });
        return;
      }
      try {
        const profile = await fetchOrCreateUserProfile(user);
        if (!cancelled) setState({ loading: false, user, profile, error: '' });
      } catch (err) {
        if (!cancelled) setState({ loading: false, user, profile: null, error: authErrorMessage(err) || 'Unable to load account profile.' });
      }
    });
    return () => { cancelled = true; unsub(); };
  }, []);

  const signOut = () => getKitchenAuth().signOut();

  if (state.loading) {
    return <AuthShell title="Loading" subtitle="Checking your account..."><div className="auth-spinner">Please wait</div></AuthShell>;
  }
  if (state.error) {
    return <AuthShell title="Account error"><div className="auth-alert error">{state.error}</div><button className="auth-secondary" onClick={signOut}>Sign out</button></AuthShell>;
  }
  if (!state.user) return mode === 'signup' ? <SignupForm onMode={setMode} /> : <LoginForm onMode={setMode} />;
  const accountStatus = normalizeAccountStatus(state.profile?.status);
  if (accountStatus === ACCOUNT_STATUS.PENDING) return <PendingApproval profile={state.profile} onSignOut={signOut} />;
  if (accountStatus !== ACCOUNT_STATUS.APPROVED) return <BlockedAccount profile={state.profile} onSignOut={signOut} />;

  return children({ user: state.user, profile: state.profile, signOut });
}

function AdminApprovalsScreen({ onBack, currentUserProfile }) {
  const [users, setUsers] = useStateAuth([]);
  const [loading, setLoading] = useStateAuth(true);
  const [error, setError] = useStateAuth('');
  const [busyUserId, setBusyUserId] = useStateAuth('');

  useEffectAuth(() => {
    let unsub;
    try {
      unsub = getKitchenDb().collection('users')
        .orderBy('createdAt', 'desc')
        .onSnapshot((snap) => {
          setUsers(snap.docs.map((doc) => cleanProfile(doc.id, doc.data())));
          setLoading(false);
        }, (err) => {
          setError(err.message || 'Unable to load account requests.');
          setLoading(false);
        });
    } catch (err) {
      setError(err.message || 'Unable to load account requests.');
      setLoading(false);
    }
    return () => { if (unsub) unsub(); };
  }, []);

  const updateUser = async (uid, patch) => {
    setError('');
    setBusyUserId(uid);
    try {
      await getKitchenDb().collection('users').doc(uid).set(Object.assign({}, patch, {
        uid,
        updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
        approvedBy: currentUserProfile?.uid || null,
      }), { merge: true });
    } catch (err) {
      setError(authErrorMessage(err));
    } finally {
      setBusyUserId('');
    }
  };

  return (
    <div className="view view-enter">
      <SubHead onBack={onBack} en="Approve Accounts" hi="Admin" stats={[{ v: users.filter((u) => u.status === ACCOUNT_STATUS.PENDING).length, l: 'PENDING', urgent: true }, { v: users.length, l: 'USERS' }]} />
      <div className="admin-approvals">
        {error && <div className="auth-alert error">{error}</div>}
        {loading && <div className="empty-state"><strong>Loading account requests...</strong></div>}
        {!loading && users.map((user) => (
          <div className="approval-row" key={user.uid}>
            <div className="approval-avatar">{displayInitials(user.fullName)}</div>
            <div className="approval-main">
              <strong>{user.fullName}</strong>
              <span>{user.email} · {user.storeName}</span>
              <small>Status: {user.status}</small>
            </div>
            <select value={user.role} disabled={busyUserId === user.uid} onChange={(e) => updateUser(user.uid, { role: normalizeRole(e.target.value), requestedRole: normalizeRole(e.target.value) })}>
              {ROLE_ORDER.map((role) => <option key={role} value={role}>{roleLabel(role)}</option>)}
            </select>
            <select value={user.storeId} disabled={busyUserId === user.uid} onChange={(e) => {
              const store = STORES.find((s) => s.storeId === e.target.value) || DEFAULT_STORE;
              updateUser(user.uid, { storeId: store.storeId, storeName: store.displayName });
            }}>
              {STORES.map((store) => <option key={store.storeId} value={store.storeId}>{store.displayName}</option>)}
            </select>
            <div className="approval-actions">
              <button disabled={busyUserId === user.uid} onClick={() => updateUser(user.uid, { status: ACCOUNT_STATUS.APPROVED })}>Approve</button>
              <button disabled={busyUserId === user.uid} onClick={() => updateUser(user.uid, { status: ACCOUNT_STATUS.REJECTED })}>Reject</button>
              <button disabled={busyUserId === user.uid} className="danger" onClick={() => updateUser(user.uid, { status: ACCOUNT_STATUS.DISABLED })}>Disable</button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, {
  AuthGate,
  AdminApprovalsScreen,
  displayInitials,
  firstNameLabel,
  greetingForNow,
  fetchOrCreateUserProfile,
  normalizeAccountStatus,
  authErrorMessage,
});
