import { useState, type FormEvent } from 'react';
import { useNavigate } from 'react-router-dom';
import { Eye, EyeSlash } from '@phosphor-icons/react';
import { useConvex } from 'convex/react';
import { usePlatform } from '../../platform';
import { useSearch } from '../../contexts/SearchContext';
import { api } from '../../../../../convex/_generated/api';
import { AuthLayout } from './AuthLayout';
import styles from './LoginPage.module.css';

export function LoginPage() {
	const navigate = useNavigate();
	const convex = useConvex();
	const { crypto, session } = usePlatform();
	const searchCtx = useSearch();

	const [username, setUsername] = useState('');
	const [password, setPassword] = useState('');
	const [showPassword, setShowPassword] = useState(false);
	const [error, setError] = useState<string | null>(null);
	const [loading, setLoading] = useState(false);

	async function decryptEncryptedField(encryptedJson: string, keyHex: string): Promise<string> {
		const obj = JSON.parse(encryptedJson);
		return crypto.decryptData(obj.content, keyHex, obj.iv, obj.tag);
	}

	const handleSubmit = async (e: FormEvent) => {
		e.preventDefault();
		setError(null);
		setLoading(true);

		try {
			const { salt } = await convex.query(api.auth.getSalt, { username });
			const { dek, dak } = await crypto.deriveAuthKeys(password, salt);

			const searchKeys = await crypto.deriveAuthKeys(password, 'searchdb-' + username);
			sessionStorage.setItem('searchDbKey', searchKeys.dak);

			const verifyData = await convex.mutation(api.auth.verifyUser, { username, dak });
			if (verifyData.error) throw new Error(verifyData.error);

			if (verifyData.userId) localStorage.setItem('userId', verifyData.userId);

			const mkHex = await decryptEncryptedField(verifyData.encryptedMK, dek);
			sessionStorage.setItem('masterKey', mkHex);

			const encryptedPrivateKeysObj = JSON.parse(verifyData.encryptedPrivateKeys);
			const signingKey = await decryptEncryptedField(JSON.stringify(encryptedPrivateKeysObj.ed), mkHex);
			const rsaPriv = await decryptEncryptedField(JSON.stringify(encryptedPrivateKeysObj.rsa), mkHex);

			sessionStorage.setItem('signingKey', signingKey);
			sessionStorage.setItem('privateKey', rsaPriv);
			localStorage.setItem('username', username);
			if (verifyData.publicKey) localStorage.setItem('publicKey', verifyData.publicKey);

			if (session) {
				try {
					await session.save({
						userId: verifyData.userId,
						username,
						publicKey: verifyData.publicKey || '',
						signingKey,
						privateKey: rsaPriv,
						masterKey: mkHex,
						searchDbKey: searchKeys.dak,
						savedAt: Date.now(),
					});
				} catch (err) {
					console.warn('Session persistence unavailable:', err);
				}
			}

			searchCtx?.initialize();
			navigate('/channels/@me');
		} catch (err: any) {
			setError(err?.message ?? 'Login failed');
		} finally {
			setLoading(false);
		}
	};

	return (
		<AuthLayout>
			<h1 className={styles.title}>Welcome back</h1>

			<form onSubmit={handleSubmit} className={styles.form}>
				<div className={styles.field}>
					<label className={styles.label}>Username</label>
					<input
						type="text"
						className={styles.input}
						value={username}
						onChange={(e) => setUsername(e.target.value)}
						placeholder="Enter your username"
						required
						autoFocus
						disabled={loading}
					/>
				</div>

				<div className={styles.field}>
					<label className={styles.label}>Password</label>
					<div className={styles.inputWrap}>
						<input
							type={showPassword ? 'text' : 'password'}
							className={`${styles.input} ${styles.inputWithTrailing}`}
							value={password}
							onChange={(e) => setPassword(e.target.value)}
							placeholder="Enter your password"
							required
							disabled={loading}
						/>
						<button
							type="button"
							className={styles.trailingIconButton}
							onClick={() => setShowPassword((v) => !v)}
							aria-label={showPassword ? 'Hide password' : 'Show password'}
							tabIndex={-1}
						>
							{showPassword ? <EyeSlash size={18} weight="regular" /> : <Eye size={18} weight="regular" />}
						</button>
					</div>
				</div>

				{error && <div className={styles.error}>{error}</div>}

				<button type="submit" className={styles.submitButton} disabled={loading}>
					{loading ? 'Logging in…' : 'Log in'}
				</button>

				<div className={styles.divider}>
					<hr className={styles.dividerLine} />
					<span className={styles.dividerText}>OR</span>
					<hr className={styles.dividerLine} />
				</div>

				<div className={styles.footer}>
					<span className={styles.footerText}>Need an account? </span>
					<button type="button" className={styles.footerLink} onClick={() => navigate('/register')}>
						Register
					</button>
				</div>
				<div style={{ textAlign: 'center', marginTop: 8 }}>
					<button
						type="button"
						className={styles.footerLink}
						onClick={() => navigate('/recovery')}
					>
						Forgot your password?
					</button>
				</div>
			</form>
		</AuthLayout>
	);
}

export default LoginPage;
