import 'package:flutter/material.dart';
import '../views/login/signup_page.dart';

/* 구글 로그인 */
import 'package:google_sign_in/google_sign_in.dart';
import 'package:firebase_auth/firebase_auth.dart';

/* 애플 로그인 */
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'dart:io' show Platform;
import 'dart:math';
import 'dart:convert';
import 'package:crypto/crypto.dart';

/* 안내 모달창 */
import 'response_dialog.dart';

/* 우리의 Api 모듈 */
import '../plugins/api.dart';

/* 설정 */
import '../config/config.dart';

// 회원가입 방법 선택 모달 위젯
class SignUpDialog extends StatefulWidget {
  const SignUpDialog({Key? key}) : super(key: key);

  @override
  State<SignUpDialog> createState() => _SignUpDialogState();
}

class _SignUpDialogState extends State<SignUpDialog> {
  // 구글 로그인 객체
  final GoogleSignIn _googleSignIn = GoogleSignIn(scopes: <String>['email']);
  
  // 로딩 상태 관리
  bool _isLoading = false;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Dialog(
          backgroundColor: Colors.white,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(16),
          ),
          child: Container(
            padding: const EdgeInsets.all(20),
            width: 300,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                // 제목
                const Text(
                  'Sign Up Method',
                  style: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                    color: Colors.black,
                  ),
                ),
                const SizedBox(height: 24),

                // 이메일 회원가입 버튼
                SizedBox(
                  width: double.infinity,
                  child: ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.white,
                      foregroundColor: Colors.black,
                      side: const BorderSide(color: Colors.black),
                      padding: const EdgeInsets.symmetric(vertical: 12),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(8),
                      ),
                    ),
                    onPressed: () {
                      Navigator.pop(context);
                      Navigator.pushAndRemoveUntil(
                        context,
                        MaterialPageRoute(builder: (_) => const SignUpPage()),
                        (route) => false,
                      );
                    },
                    child: const Text(
                      'Sign up with Email',
                      style: TextStyle(fontSize: 16),
                    ),
                  ),
                ),
                const SizedBox(height: 12),

                // 구글 회원가입 버튼
                SizedBox(
                  width: double.infinity,
                  child: ElevatedButton.icon(
                    icon: Container(
                      width: 24,
                      height: 24,
                      decoration: const BoxDecoration(
                        image: DecorationImage(
                          image: AssetImage('assets/images/icons8-google-logo-48.png'),
                          fit: BoxFit.contain,
                        ),
                      ),
                    ),
                    label: const Text(
                      'Sign up with Google',
                      style: TextStyle(fontSize: 16),
                    ),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.white,
                      foregroundColor: Colors.black,
                      side: const BorderSide(color: Colors.black),
                      padding: const EdgeInsets.symmetric(vertical: 12),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(8),
                      ),
                    ),
                    onPressed: _googleSignUp,
                  ),
                ),
                const SizedBox(height: 12),

                // 애플 회원가입 버튼 - iOS에서만 표시
                if (!Platform.isAndroid)
                  SizedBox(
                    width: double.infinity,
                    child: ElevatedButton.icon(
                      icon: const Icon(
                        Icons.apple,
                        size: 24,
                        color: Colors.black,
                      ),
                      label: const Text(
                        'Sign up with Apple',
                        style: TextStyle(fontSize: 16),
                      ),
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.white,
                        foregroundColor: Colors.black,
                        side: const BorderSide(color: Colors.black),
                        padding: const EdgeInsets.symmetric(vertical: 12),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(8),
                        ),
                      ),
                      onPressed: () {
                        _appleSignUp();
                      },
                    ),
                  ),
              ],
            ),
          ),
        ),
        // 로딩 인디케이터
        if (_isLoading)
          Container(
            color: Colors.black54,
            alignment: Alignment.center,
            child: const CircularProgressIndicator(color: Colors.white),
          ),
      ],
    );
  }

  
  // ─────────────────────────────────────────
  // (D3) 구글 회원가입
  // ─────────────────────────────────────────
  Future<void> _googleSignUp() async {
    setState(() => _isLoading = true);
    
    final agreed = await _showTermsModal();
    if (agreed != true) {
      setState(() => _isLoading = false);
      return;
    }

    try {
      // (2) 구글 계정 선택
      final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
      if (googleUser == null) {
        // 사용자가 회원가입 창에서 취소
        return;
      }

      // (3) 구글 인증 정보
      final GoogleSignInAuthentication googleAuth = await googleUser.authentication;

      // (4) FirebaseAuth Credential
      final AuthCredential credential = GoogleAuthProvider.credential(
        accessToken: googleAuth.accessToken,
        idToken: googleAuth.idToken,
      );

      // (5) FirebaseAuth로 "회원가입" 시도
      final UserCredential userCredential = await FirebaseAuth.instance.signInWithCredential(credential);
      final User? user = userCredential.user;
      if (user == null) {
        showResponseDialog(context, 'Error' /* 오류 */, 'Google account authentication failed.'
            /* 구글계정 인증에 실패했습니다. */);
        return;
      }

      // (6) idToken 추출 후, 서버에 회원가입 요청
      final idToken = await user.getIdToken();
      final requestBody = {
        'id_token': idToken,
      };

      final response = await Api.serverRequest(uri: '/user/google/signup', body: requestBody);
      if (response['result'] == 'OK') {
        final resp = response['response'] ?? {};
        if (resp['result'] == 'OK') {
          // 회원가입 성공 안내
          showResponseDialog(context, 'Sign-up Complete' /* 회원가입 완료 */, 'Google sign-up has been completed.'
              /* 구글 회원가입이 완료되었습니다. */);
        } else {
          // 실패 시
          final msgTitle = resp['response_info']?['msg_title'] ?? 'Error' /* 오류 */;
          final msgContent = resp['response_info']?['msg_content'] ?? 'Failed to sign up.' 
              /* 회원가입에 실패했습니다. */;
          showResponseDialog(context, msgTitle, msgContent);
        }
      } else {
        showResponseDialog(context, 'Error' /* 오류 */, 'Google sign-up request failed.'
            /* 구글 회원가입 요청 실패 */);
      }
    } catch (e) {
      showResponseDialog(context, 'Error' /* 오류 */, 'An error occurred during Google sign-up.\n$e'
          /* 구글 회원가입 중 오류가 발생했습니다.\n$e */);
    } finally {
      setState(() => _isLoading = false);
    }
  }


  // ─────────────────────────────────────────
  // (D4) 애플 회원가입
  // ─────────────────────────────────────────
  Future<void> _appleSignUp() async {
    // 안드로이드 기기 체크
    if (Platform.isAndroid) {
      showResponseDialog(
        context,
        '사용 불가',  // 제목
        '애플 회원가입은 안드로이드 기기에서 제공되지 않습니다.',  // 내용
      );
      return;
    }

    setState(() => _isLoading = true);
    
    final agreed = await _showTermsModal();
    if (agreed != true) {
      setState(() => _isLoading = false);
      return;
    }

    try {
      // 1. 애플 로그인 credential 획득
      final rawNonce = generateNonce();
      final nonce = sha256ofString(rawNonce);

      final appleCredential = await SignInWithApple.getAppleIDCredential(
            scopes: [
              AppleIDAuthorizationScopes.email,
              AppleIDAuthorizationScopes.fullName,
            ],
          );
      print('appleCredential: $appleCredential');

      // 2. Firebase credential 생성
      final oauthProvider = OAuthProvider('apple.com');
      print('oauthProvider: $oauthProvider');
      final credential = oauthProvider.credential(
        idToken: appleCredential.identityToken,
        accessToken: appleCredential.authorizationCode,
      );
      print('credential: $credential');

      // 3. Firebase 인증
      final userCredential = await FirebaseAuth.instance.signInWithCredential(credential);
      print('userCredential: $userCredential');
      final user = userCredential.user;
      print('user: $user');

      if (user == null) {
        showResponseDialog(context, 'Error', 'Apple account authentication failed.');
        return;
      }

      // 4. 서버에 회원가입 요청
      final idToken = await user.getIdToken();
      final requestBody = {
        'id_token': idToken,
      };

      final response = await Api.serverRequest(uri: '/user/apple/signup', body: requestBody);
      if (response['result'] == 'OK') {
        final resp = response['response'] ?? {};
        if (resp['result'] == 'OK') {
          showResponseDialog(
            context, 
            'Sign-up Complete',
            'Apple sign-up has been completed.'
          );
        } else {
          final msgTitle = resp['response_info']?['msg_title'] ?? 'Error';
          final msgContent = resp['response_info']?['msg_content'] ?? 'Failed to sign up.';
          showResponseDialog(context, msgTitle, msgContent);
        }
      } else {
        showResponseDialog(
          context, 
          'Error',
          'Apple sign-up request failed.'
        );
      }
    } catch (e) {
      showResponseDialog(
        context, 
        'Error',
        'An error occurred during Apple sign-up.\n$e'
      );
    } finally {
      setState(() => _isLoading = false);
    }
  }

  // nonce 생성 유틸리티 함수들 추가
  String generateNonce([int length = 32]) {
    const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._';
    final random = Random.secure();
    return List.generate(length, (_) => charset[random.nextInt(charset.length)]).join();
  }

  String sha256ofString(String input) {
    final bytes = utf8.encode(input);
    final digest = sha256.convert(bytes);
    return digest.toString();
  }


  // ─────────────────────────────────────────
  // (E) 약관 모달 (개인정보 수집 동의)
  // ─────────────────────────────────────────
  Future<bool?> _showTermsModal() async {
    return showDialog<bool>(
      context: context,
      barrierDismissible: false,
      builder: (ctx) {
        return AlertDialog(
          backgroundColor: Colors.white,
          title: const Text(
            'Privacy Collection and Usage Agreement' 
            /* 개인정보 수집 및 이용 동의서 */,
            style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
          ),
          content: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: const [
                Text(
                  Config.termsOfService,
                  style: const TextStyle(fontSize: 14),
                ),
              ],
            ),
          ),
          actions: [
            TextButton(
              style: TextButton.styleFrom(
                backgroundColor: Colors.black,
                foregroundColor: Colors.white,
              ),
              onPressed: () => Navigator.pop(ctx, false),
              child: Text('Disagree' 
                  /* 거부 */),
            ),
            TextButton(
              style: TextButton.styleFrom(
                backgroundColor: Colors.black,
                foregroundColor: Colors.white,
              ),
              onPressed: () => Navigator.pop(ctx, true),
              child: Text('Agree' 
                  /* 동의 */),
            ),
          ],
        );
      },
    );
  }
}