// lib/screens/auth/otp_screen.dart
import 'dart:async';
import 'dart:convert';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:fl_ks_smart_society_user/localization/localization_const.dart';
import 'package:fl_ks_smart_society_user/theme/theme.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:pinput/pinput.dart';
import 'package:shared_preferences/shared_preferences.dart';

class OTPScreen extends StatefulWidget {
  const OTPScreen({super.key});

  @override
  State<OTPScreen> createState() => _OTPScreenState();
}

class _OTPScreenState extends State<OTPScreen> {
  // Timer
  Timer? countdownTimer;
  Duration myDuration = const Duration(minutes: 1);

  // Firebase & OTP
  bool _firebaseInitialized = false;
  bool _verificationStarted = false;
  String? _phoneNumber;
  String? _verificationId;

  // UI / State
  bool _isLoading = false;

  // Controllers
  final TextEditingController _otpController = TextEditingController();

  // Backend URL
  final String backendLoginUrl = "https://gelite.asia/api/login_otp.php";

  @override
  void initState() {
    super.initState();
    _initFirebase();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();

    // Receive phoneNumber from Navigator arguments
    final args =
    ModalRoute.of(context)?.settings.arguments as Map<String, dynamic>?;

    if (args != null && _phoneNumber == null) {
      // Support both "phone_no" (from LoginScreen) and "phoneNumber" if used elsewhere
      final argPhone =
      (args['phone_no'] ?? args['phoneNumber'])?.toString();

      _phoneNumber = argPhone;
      print(
          "📱 [OTPScreen] Received phoneNumber => $_phoneNumber from args: $args");

      _maybeStartVerification();
    }
  }

  Future<void> _initFirebase() async {
    try {
      print("🔄 [OTPScreen] Initializing Firebase...");
      if (Firebase.apps.isEmpty) {
        await Firebase.initializeApp();
      }
      _firebaseInitialized = true;
      print("✅ [OTPScreen] Firebase initialized");
      _maybeStartVerification();
    } catch (e) {
      print("⚠️ [OTPScreen] Firebase init failed: $e");
    }
  }

  void _maybeStartVerification() {
    print(
        "🔎 [OTPScreen] _maybeStartVerification called with phone: $_phoneNumber, firebase: $_firebaseInitialized");

    if (!_firebaseInitialized) {
      print("⏳ [OTPScreen] Waiting: Firebase not ready");
      return;
    }
    if (_phoneNumber == null || _phoneNumber!.isEmpty) {
      print("⏳ [OTPScreen] Waiting: phoneNumber not set");
      return;
    }
    if (_verificationStarted) {
      print("ℹ️ [OTPScreen] Verification already started");
      return;
    }

    _verificationStarted = true;
    _startPhoneVerification();
  }

  // ---------------- Timer utils ----------------
  void startTimer() {
    countdownTimer?.cancel();
    countdownTimer =
        Timer.periodic(const Duration(seconds: 1), (_) => setCountDown());
  }

  void stopTimer() {
    countdownTimer?.cancel();
  }

  void resetTimer() {
    stopTimer();
    setState(() => myDuration = const Duration(minutes: 1));
  }

  void setCountDown() {
    const reduceSecondsBy = 1;
    if (mounted) {
      setState(() {
        final seconds = myDuration.inSeconds - reduceSecondsBy;
        if (seconds < 0) {
          countdownTimer?.cancel();
        } else {
          myDuration = Duration(seconds: seconds);
        }
      });
    }
  }

  // ---------------- Firebase OTP Verification ----------------
  Future<void> _startPhoneVerification({bool isResend = false}) async {
    if (_phoneNumber == null || _phoneNumber!.isEmpty) {
      print("❌ [OTP] Cannot start verification: phoneNumber is null/empty");
      return;
    }

    setState(() {
      _isLoading = true;
    });

    print(
        "📤 [OTP Firebase] Start verifyPhoneNumber => phone: $_phoneNumber, isResend: $isResend");

    // start countdown timer when sending OTP
    resetTimer();
    startTimer();

    try {
      await FirebaseAuth.instance.verifyPhoneNumber(
        phoneNumber: _phoneNumber!,
        timeout: const Duration(seconds: 60),
        verificationCompleted: (PhoneAuthCredential credential) async {
          print(
              "🔁 [OTP Firebase] verificationCompleted => credential: ${credential.toString()}");

          // Auto-fill OTP if available
          final smsCode = credential.smsCode;
          if (smsCode != null) {
            print(
                "✅ [OTP Firebase] Auto-received smsCode from Firebase => $smsCode");
            _otpController.text = smsCode;
          }

          try {
            final userCred =
            await FirebaseAuth.instance.signInWithCredential(credential);
            print(
                "✅ [OTP Firebase] Auto signInWithCredential success => uid: ${userCred.user?.uid}");

            await _postOtpLoginToBackend();
          } catch (e) {
            print("❌ [OTP Firebase] verificationCompleted signIn error: $e");
            _showSnack("Auto verification failed", isError: true);
          }
        },
        verificationFailed: (FirebaseAuthException e) {
          print(
              "❌ [OTP Firebase] verificationFailed => code: ${e.code}, message: ${e.message}");
          _showSnack(e.message ?? "Verification failed", isError: true);
          setState(() {
            _isLoading = false;
          });
        },
        codeSent: (String verificationId, int? resendToken) {
          _verificationId = verificationId;
          print(
              "📨 [OTP Firebase] codeSent => verificationId: $verificationId, resendToken: $resendToken");
          setState(() {
            _isLoading = false;
          });
        },
        codeAutoRetrievalTimeout: (String verificationId) {
          _verificationId = verificationId;
          print(
              "⏳ [OTP Firebase] codeAutoRetrievalTimeout => verificationId: $verificationId");
        },
      );
    } catch (e) {
      print("❌ [OTP Firebase] verifyPhoneNumber exception => $e");
      _showSnack("Error sending OTP", isError: true);
      setState(() {
        _isLoading = false;
      });
    }
  }

  Future<void> _resendOtp() async {
    if (myDuration != const Duration(seconds: 0)) {
      print("⏳ [OTP] Resend tapped but timer not finished yet");
      return;
    }
    print("🔁 [OTP] Resend OTP tapped");
    await _startPhoneVerification(isResend: true);
  }

  // ---------------- OTP Verify & Backend Login ----------------
  Future<void> _verifyOtpAndLogin(String smsCode) async {
    print(
        "📤 [OTP Verify] Request => verificationId: $_verificationId, smsCode: $smsCode");

    if (_verificationId == null || _verificationId!.isEmpty) {
      _showSnack("Request OTP first", isError: true);
      print("❌ [OTP Verify] verificationId is empty");
      return;
    }

    if (smsCode.isEmpty) {
      _showSnack("Enter OTP", isError: true);
      print("❌ [OTP Verify] OTP code empty");
      return;
    }

    setState(() => _isLoading = true);

    try {
      final credential = PhoneAuthProvider.credential(
        verificationId: _verificationId!,
        smsCode: smsCode,
      );

      print(
          "📤 [OTP Verify] Firebase PhoneAuthProvider.credential => {\"verificationId\":\"$_verificationId\",\"smsCode\":\"$smsCode\"}");

      final userCredential =
      await FirebaseAuth.instance.signInWithCredential(credential);
      print(
          "✅ [OTP Verify] Firebase signInWithCredential success => {\"uid\":\"${userCredential.user?.uid}\",\"phone\":\"${userCredential.user?.phoneNumber}\"}");

      await _postOtpLoginToBackend();
    } catch (e) {
      print("❌ [OTP Verify] Exception => $e");
      _showSnack("OTP verification failed", isError: true);
    } finally {
      if (mounted) setState(() => _isLoading = false);
      print("ℹ️ [OTP Verify] isLoading set to false");
    }
  }

  Future<void> _postOtpLoginToBackend() async {
    if (_phoneNumber == null) {
      print("❌ [OTP Backend Login] phoneNumber is null");
      _showSnack("Invalid phone number", isError: true);
      return;
    }

    final body = {
      "phone_no": _phoneNumber,
      "otp_login": true,
    };

    final String requestJson = jsonEncode(body);
    print(
        "📤 [OTP Backend Login] HTTP POST => URL: $backendLoginUrl, Request JSON: $requestJson");

    try {
      final resp = await http.post(
        Uri.parse(backendLoginUrl),
        headers: {"Content-Type": "application/json"},
        body: requestJson,
      );

      print(
          "📥 [OTP Backend Login] HTTP Response => statusCode: ${resp.statusCode}, body: ${resp.body}");

      if (resp.statusCode == 200) {
        Map<String, dynamic> jsonResp = {};
        try {
          jsonResp = jsonDecode(resp.body);
          print("🔎 [OTP Backend Login] Decoded JSON Response => $jsonResp");
        } catch (e) {
          print("❌ [OTP Backend Login] JSON decode error => $e");
        }

        if (jsonResp['status'] == 'success') {
          final user = _extractUserFromResponse(jsonResp);
          await _saveUserToPrefs(user);
          _showSnack("Login successful");
          print(
              "✅ [OTP Backend Login] Success => Navigating to '/bottombar' with saved user");

          stopTimer();
          if (mounted) {
            Navigator.pushReplacementNamed(context, '/bottombar');
          }
        } else {
          final msg = jsonResp['message']?.toString() ?? "OTP login failed";
          _showSnack(msg, isError: true);
          print("⚠️ [OTP Backend Login] Failure => message: $msg");
        }
      } else {
        _showSnack("Server error: ${resp.statusCode}", isError: true);
        print("❌ [OTP Backend Login] Server error => ${resp.statusCode}");
      }
    } catch (e) {
      print("❌ [OTP Backend Login] Exception => $e");
      _showSnack("Network error", isError: true);
    }
  }

  Map<String, dynamic> _extractUserFromResponse(Map<String, dynamic> respJson) {
    print("🔍 [OTP Backend Login] Extracting user from JSON => $respJson");
    Map<String, dynamic> user = {};
    if (respJson['data'] != null) {
      if (respJson['data'] is Map && respJson['data']['user'] != null) {
        user = Map<String, dynamic>.from(respJson['data']['user']);
        print("✅ [User Extract] Extracted from data.user => $user");
      } else if (respJson['data'] is Map) {
        user = Map<String, dynamic>.from(respJson['data']);
        print("✅ [User Extract] Extracted from data => $user");
      }
    }
    print("👤 [User Extract] Final user JSON => $user");
    return user;
  }

  // ---------------- SharedPreferences save ----------------
  Future<void> _saveUserToPrefs(Map<String, dynamic> user) async {
    print("💾 [SharedPrefs] Saving user JSON => $user");
    final prefs = await SharedPreferences.getInstance();

    if (user['phone_no'] != null) {
      await prefs.setString('phone_no', user['phone_no'].toString());
      print(
          "✅ [SharedPrefs] Saved \"phone_no\" => \"${user['phone_no'].toString()}\"");
    }
    if (user['id'] != null) {
      final id = int.tryParse(user['id'].toString()) ?? 0;
      await prefs.setInt('id', id);
      print("✅ [SharedPrefs] Saved \"id\" => $id");
    }
    if (user['name'] != null) {
      await prefs.setString('name', user['name'].toString());
      print("✅ [SharedPrefs] Saved \"name\" => \"${user['name'].toString()}\"");
    }
    if (user['role'] != null) {
      await prefs.setString('role', user['role'].toString());
      print("✅ [SharedPrefs] Saved \"role\" => \"${user['role'].toString()}\"");
    }
    if (user['profile_photo'] != null) {
      await prefs.setString('profile_photo', user['profile_photo'].toString());
      print("✅ [SharedPrefs] Saved \"profile_photo\"");
    }
    if (user['vertical'] != null) {
      await prefs.setString('vertical', user['vertical'].toString());
      print(
          "✅ [SharedPrefs] Saved \"vertical\" => \"${user['vertical'].toString()}\"");
    }
    if (user['fcm_token'] != null) {
      await prefs.setString('fcm_token', user['fcm_token'].toString());
      print("✅ [SharedPrefs] Saved \"fcm_token\"");
    }
    if (user['created_at'] != null) {
      await prefs.setString('created_at', user['created_at'].toString());
      print(
          "✅ [SharedPrefs] Saved \"created_at\" => \"${user['created_at'].toString()}\"");
    }
    if (user['token'] != null) {
      await prefs.setString('token', user['token'].toString());
      print("✅ [SharedPrefs] Saved \"token\"");
    }

    print("💾 [SharedPrefs] User saved to SharedPreferences (complete)");
  }

  // ---------------- UI ----------------
  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.sizeOf(context);
    String strDigits(int n) => n.toString().padLeft(2, '0');
    final minutes = strDigits(myDuration.inMinutes.remainder(60));
    final seconds = strDigits(myDuration.inSeconds.remainder(60));

    return Scaffold(
      body: Stack(
        children: [
          Container(
            height: size.height,
            width: size.width,
            decoration: const BoxDecoration(
              image: DecorationImage(
                image: AssetImage("assets/auth/bg-image.png"),
                fit: BoxFit.cover,
              ),
            ),
            child: Container(
              decoration: BoxDecoration(
                gradient: LinearGradient(
                  begin: Alignment.topCenter,
                  end: Alignment.bottomCenter,
                  stops: const [0.37, 1.0],
                  colors: [
                    whiteColor,
                    primaryColor.withOpacity(0.5),
                  ],
                ),
              ),
              child: Column(
                children: [
                  backArrow(context),
                  Expanded(
                    child: ListView(
                      physics: const BouncingScrollPhysics(),
                      padding: const EdgeInsets.only(
                        bottom: fixPadding * 2.0,
                        left: fixPadding * 2.0,
                        right: fixPadding * 2.0,
                      ),
                      children: [
                        otpContent(),
                        heightSpace,
                        heightSpace,
                        heightSpace,
                        heightSpace,
                        height5Space,
                        titleAndTimer(minutes, seconds),
                        heightSpace,
                        height5Space,
                        otpField(),
                        heightSpace,
                        heightSpace,
                        heightSpace,
                        heightSpace,
                        verifyButton(),
                        heightSpace,
                        resendText(),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),

          // Loading overlay
          if (_isLoading)
            Container(
              color: Colors.black.withOpacity(0.2),
              child: const Center(child: CircularProgressIndicator()),
            ),
        ],
      ),
    );
  }

  Widget resendText() {
    return Text.rich(
      TextSpan(
        text: tr(context, 'otp.received_text'),
        style: regular16Black,
        children: [
          const TextSpan(text: " "),
          TextSpan(
            text: tr(context, 'otp.resend'),
            style: medium16Primary,
            recognizer: TapGestureRecognizer()
              ..onTap = () async {
                if (myDuration == const Duration(seconds: 0)) {
                  await _resendOtp();
                } else {
                  print(
                      "⏳ [OTP UI] Resend tapped but timer not finished (remaining: ${myDuration.inSeconds}s)");
                }
              },
          ),
        ],
      ),
      textAlign: TextAlign.center,
    );
  }

  Widget verifyButton() {
    return GestureDetector(
      onTap: () {
        final otp = _otpController.text.trim();
        print("👉 [OTP UI] Verify button tapped with OTP: \"$otp\"");
        _verifyOtpAndLogin(otp);
      },
      child: Container(
        width: double.maxFinite,
        padding: const EdgeInsets.symmetric(
          horizontal: fixPadding * 2.0,
          vertical: fixPadding * 1.1,
        ),
        decoration: BoxDecoration(
          color: primaryColor,
          borderRadius: BorderRadius.circular(10.0),
          boxShadow: buttonShadow,
        ),
        alignment: Alignment.center,
        child: Text(
          tr(context, 'otp.verify'),
          style: medium20White,
          overflow: TextOverflow.ellipsis,
          textAlign: TextAlign.center,
        ),
      ),
    );
  }

  Widget otpField() {
    return Pinput(
      length: 6,
      controller: _otpController,
      onCompleted: (value) {
        print("📩 [OTP UI] Pinput onCompleted => \"$value\"");
        _verifyOtpAndLogin(value.trim());
      },
      defaultPinTheme: PinTheme(
        height: 50.0,
        width: 50.0,
        textStyle: medium20Primary,
        decoration: BoxDecoration(
          color: whiteColor,
          borderRadius: BorderRadius.circular(10.0),
          boxShadow: boxShadow,
        ),
      ),
      focusedPinTheme: PinTheme(
        height: 50.0,
        width: 50.0,
        textStyle: medium20Primary,
        decoration: BoxDecoration(
          color: whiteColor,
          borderRadius: BorderRadius.circular(10.0),
          boxShadow: boxShadow,
          border: Border.all(color: primaryColor),
        ),
      ),
    );
  }

  Widget titleAndTimer(String minutes, String seconds) {
    return Row(
      children: [
        Expanded(
          child: Text(
            tr(context, 'otp.OTP'),
            style: regular16Black,
          ),
        ),
        widthSpace,
        Text(
          "${tr(context, 'otp.resend_in')} $minutes : $seconds",
          style: regular16Black,
        ),
      ],
    );
  }

  Widget otpContent() {
    return Column(
      children: [
        Text(
          tr(context, 'otp.enter_OTP'),
          style: medium20Primary,
          textAlign: TextAlign.center,
        ),
        height5Space,
        Text(
          tr(context, 'otp.digit_text'),
          style: regular16Grey,
        ),
        if (_phoneNumber != null) ...[
          height5Space,
          Text(
            _phoneNumber!,
            style: regular16Grey,
          ),
        ],
      ],
    );
  }

  Widget backArrow(BuildContext context) {
    return AppBar(
      automaticallyImplyLeading: false,
      backgroundColor: Colors.transparent,
      systemOverlayStyle: const SystemUiOverlayStyle(
        statusBarColor: Colors.transparent,
        statusBarIconBrightness: Brightness.dark,
      ),
      elevation: 0.0,
      shadowColor: Colors.transparent,
      centerTitle: false,
      leading: IconButton(
        onPressed: () {
          print("🔙 [OTPScreen] Back pressed");
          stopTimer();
          Navigator.pop(context);
        },
        icon: const Icon(
          Icons.arrow_back,
          color: blackColor,
        ),
      ),
    );
  }

  void _showSnack(String message, {bool isError = false}) {
    if (!mounted) return;
    print("🔔 [SnackBar] ${isError ? 'ERROR' : 'INFO'} => \"$message\"");
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        backgroundColor: isError ? Colors.red : Colors.green,
        behavior: SnackBarBehavior.floating,
        duration: const Duration(seconds: 2),
      ),
    );
  }

  @override
  void dispose() {
    print("🧹 [OTPScreen] Disposing resources");
    countdownTimer?.cancel();
    _otpController.dispose();
    super.dispose();
  }
}
