import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:url_launcher/url_launcher.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @override State createState() => _LoginScreenState(); } class _LoginScreenState extends State { final _emailController = TextEditingController(); final _passwordController = TextEditingController(); final _nameController = TextEditingController(); final _codeController = TextEditingController(); bool _isLoginMode = true; bool _isUnlocked = false; bool _showInfo = false; bool _isLoading = false; int _tierToGrant = 1; static const Color terminalGreen = Color(0xFFE87D25); // --- LOGIC: REQUEST LVL 1 (FREE) --- Future _requestFreeAccess() async { final nameController = TextEditingController(); final contactController = TextEditingController(); bool isSending = false; // Internal state for the dialog showDialog( context: context, builder: (context) => StatefulBuilder( builder: (context, setDialogState) => AlertDialog( backgroundColor: Colors.black, shape: const RoundedRectangleBorder(side: BorderSide(color: terminalGreen)), title: const Text("FREE_ACCESS_REQUEST", style: TextStyle(fontSize: 14)), content: Column( mainAxisSize: MainAxisSize.min, children: [ const Text("ENTER_INFO_FOR_KEY_DELIVERY:", style: TextStyle(fontSize: 10, color: Colors.white24)), const SizedBox(height: 15), TextField(controller: nameController, decoration: const InputDecoration(labelText: "ALIAS / NAME")), const SizedBox(height: 10), TextField(controller: contactController, decoration: const InputDecoration(labelText: "EMAIL_OR_CONTACT")), ], ), actions: [ TextButton( onPressed: isSending ? null : () => Navigator.pop(context), child: const Text("[ CANCEL ]", style: TextStyle(color: Colors.white24)) ), isSending ? const Padding( padding: EdgeInsets.only(right: 20), child: CircularProgressIndicator(color: terminalGreen, strokeWidth: 2), ) : ElevatedButton( onPressed: () async { if (contactController.text.trim().isEmpty) return; setDialogState(() => isSending = true); try { await FirebaseFirestore.instance.collection('requests').add({ 'name': nameController.text.trim(), 'contact': contactController.text.trim(), 'timestamp': FieldValue.serverTimestamp(), 'status': 'pending', 'requestedTier': 1, 'origin': 'FREE_REQUEST' }); if (!mounted) return; Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("SIGNAL_SENT: SAGE_WILL_TRANSMIT_KEY"), backgroundColor: terminalGreen) ); } catch (e) { setDialogState(() => isSending = false); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("UPLINK_ERROR: $e"), backgroundColor: Colors.red) ); } } }, child: const Text("[ SEND_REQUEST ]") ) ], ), ), ); } // --- LOGIC: VERIFY INVITE KEY --- Future _verifyInviteCode() async { if (_codeController.text.isEmpty) return; setState(() => _isLoading = true); try { final codeDoc = await FirebaseFirestore.instance.collection('invites').doc(_codeController.text.trim().toUpperCase()).get(); if (!mounted) return; if (codeDoc.exists && codeDoc.data()?['used'] == false) { setState(() { _isUnlocked = true; _tierToGrant = codeDoc.data()?['grantTier'] ?? 1; }); } else { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("INVALID_OR_EXPIRED_KEY"), backgroundColor: Colors.red)); } } catch (e) { if (mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("SYNC_ERROR: $e"))); } finally { if (mounted) setState(() => _isLoading = false); } } // --- LOGIC: LOGIN / REGISTER --- Future _submit() async { if (_emailController.text.isEmpty || _passwordController.text.isEmpty) return; setState(() => _isLoading = true); try { if (_isLoginMode) { await FirebaseAuth.instance.signInWithEmailAndPassword(email: _emailController.text.trim(), password: _passwordController.text.trim()); } else { UserCredential userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword(email: _emailController.text.trim(), password: _passwordController.text.trim()); await FirebaseFirestore.instance.collection('invites').doc(_codeController.text.trim().toUpperCase()).update({'used': true, 'usedBy': userCredential.user!.uid}); await FirebaseFirestore.instance.collection('users').doc(userCredential.user!.uid).set({ 'email': _emailController.text.trim(), 'displayName': _nameController.text.trim(), 'role': 'fan', 'tier': _tierToGrant, 'createdAt': FieldValue.serverTimestamp(), }); } } catch (e) { if (mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.toString()), backgroundColor: Colors.red)); } finally { if (mounted) setState(() => _isLoading = false); } } void _showClaimDialog() { final claimController = TextEditingController(); showDialog( context: context, builder: (context) => AlertDialog( backgroundColor: Colors.black, shape: const RoundedRectangleBorder(side: BorderSide(color: terminalGreen)), title: const Text("CLAIM_ACCESS_KEY", style: TextStyle(fontSize: 14)), content: Column( mainAxisSize: MainAxisSize.min, children: [ const Text("ENTER_PAYPAL_EMAIL_OR_TRANS_ID:", style: TextStyle(fontSize: 10, color: Colors.white24)), const SizedBox(height: 15), TextField(controller: claimController, style: const TextStyle(color: Colors.white), decoration: const InputDecoration(hintText: "PAYPAL_RECEIPT_ID")), ], ), actions: [ TextButton(onPressed: () => Navigator.pop(context), child: const Text("[ CANCEL ]")), ElevatedButton( onPressed: () async { if (claimController.text.isEmpty) return; await FirebaseFirestore.instance.collection('requests').add({ 'id': claimController.text.trim(), 'timestamp': FieldValue.serverTimestamp(), 'status': 'pending', 'origin': 'PAYPAL_CLAIM' }); if (!mounted) return; Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("SIGNAL_SENT: SAGE_WILL_VERIFY"))); }, child: const Text("[ SUBMIT ]") ) ], ) ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(40.0), child: Column( children: [ Image.asset('assets/images/logo.png', height: 100, color: terminalGreen), const SizedBox(height: 30), if (_showInfo) _buildTierInfo() else if (_isLoginMode) _buildLoginFields() else if (!_isUnlocked) _buildCodeVerifyFields() else _buildRegistrationFields(), const SizedBox(height: 30), TextButton( onPressed: () => setState(() => _showInfo = !_showInfo), child: Text(_showInfo ? "< RETURN_TO_LOGIN" : "> VIEW_ACCESS_MATRIX", style: const TextStyle(color: Colors.white24, fontSize: 10, letterSpacing: 2)), ), ], ), ), ), ); } Widget _buildTierInfo() { return Column( children: [ const Text("--- ACCESS_LEVEL_MATRIX ---", style: TextStyle(fontWeight: FontWeight.bold, letterSpacing: 2)), const SizedBox(height: 25), _tierRow("01_OBSERVER", "FREE", "30s Previews / Read-Only Comms"), const SizedBox(height: 8), SizedBox( width: double.infinity, child: OutlinedButton( style: OutlinedButton.styleFrom(side: const BorderSide(color: terminalGreen), shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero)), onPressed: _requestFreeAccess, child: const Text("[ REQUEST_LVL_01 ]", style: TextStyle(fontSize: 10, color: terminalGreen)), ), ), const SizedBox(height: 20), _tierRow("02_COLLECTOR", "\$25/MO", "Full Archive / Active Comms"), _paypalBtn("ACQUIRE_LVL_02", "https://www.paypal.com/ncp/payment/YOUR_L2_LINK"), const SizedBox(height: 20), _tierRow("03_INVESTOR", "\$100/YR", "Extractions / Private Logs / Priority"), _paypalBtn("ACQUIRE_LVL_03", "https://www.paypal.com/ncp/payment/YOUR_L3_LINK"), const SizedBox(height: 30), const Text("PAID_BUT_NO_KEY?", style: TextStyle(color: Colors.white24, fontSize: 9)), TextButton(onPressed: _showClaimDialog, child: const Text("> LOG_PAYMENT_SIGNAL", style: TextStyle(color: terminalGreen, fontSize: 10))), ], ); } Widget _tierRow(String name, String price, String perks) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(name, style: const TextStyle(color: terminalGreen, fontWeight: FontWeight.bold, fontSize: 12)), Text(price, style: const TextStyle(color: Colors.white, fontSize: 12)), ], ), const SizedBox(height: 4), Text(perks, style: const TextStyle(color: Colors.white38, fontSize: 9)), ], ); } Widget _paypalBtn(String label, String url) { return SizedBox( width: double.infinity, child: OutlinedButton( style: OutlinedButton.styleFrom(side: const BorderSide(color: terminalGreen), shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero)), onPressed: () async { final Uri uri = Uri.parse(url); if (await canLaunchUrl(uri)) await launchUrl(uri); }, child: Text("[ $label ]", style: const TextStyle(fontSize: 10, color: terminalGreen)), ), ); } Widget _buildLoginFields() { return Column( children: [ const Text("[ SYSTEM_LOGIN_REQUIRED ]", style: TextStyle(letterSpacing: 2)), const SizedBox(height: 25), TextField(controller: _emailController, decoration: const InputDecoration(labelText: "USER_ID")), const SizedBox(height: 10), TextField(controller: _passwordController, obscureText: true, decoration: const InputDecoration(labelText: "ENCRYPT_PASS")), const SizedBox(height: 30), _isLoading ? const CircularProgressIndicator(color: terminalGreen) : ElevatedButton(onPressed: _submit, child: const Text("[ ENTER ]")), TextButton( onPressed: () => setState(() => _isLoginMode = false), child: const Text("> INITIALIZE_NEW_KEY", style: TextStyle(color: Colors.white24, fontSize: 10)) ), ], ); } Widget _buildCodeVerifyFields() { return Column( children: [ const Text("[ KEY_VALIDATION ]", style: TextStyle(letterSpacing: 2)), const SizedBox(height: 25), TextField( controller: _codeController, textAlign: TextAlign.center, style: const TextStyle(letterSpacing: 8, color: Colors.white, fontWeight: FontWeight.bold), decoration: const InputDecoration(hintText: "ENTER_KEY", hintStyle: TextStyle(color: Colors.white10)) ), const SizedBox(height: 30), _isLoading ? const CircularProgressIndicator(color: terminalGreen) : ElevatedButton(onPressed: _verifyInviteCode, child: const Text("[ VALIDATE ]")), TextButton(onPressed: () => setState(() => _isLoginMode = true), child: const Text("> BACK", style: TextStyle(color: Colors.white24, fontSize: 10))), ], ); } Widget _buildRegistrationFields() { return Column( children: [ Text("[ LVL_0${_tierToGrant}_ACCESS_GRANTED ]", style: const TextStyle(color: terminalGreen, letterSpacing: 2)), const SizedBox(height: 25), TextField(controller: _nameController, decoration: const InputDecoration(labelText: "ALIAS / NAME")), const SizedBox(height: 10), TextField(controller: _emailController, decoration: const InputDecoration(labelText: "EMAIL_ADDR")), const SizedBox(height: 10), TextField(controller: _passwordController, obscureText: true, decoration: const InputDecoration(labelText: "CREATE_PASS")), const SizedBox(height: 30), _isLoading ? const CircularProgressIndicator(color: terminalGreen) : ElevatedButton(onPressed: _submit, child: const Text("[ INITIALIZE_PROFILE ]")), ], ); } }