import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:qyuota/config/api_config.dart';
import 'dart:io';
import 'package:flutter/material.dart';

class AuthService {
  static const String tokenKey = 'auth_token';
  static const String userKey = 'user_data';
  
  static final AuthService _instance = AuthService._internal();
  factory AuthService() => _instance;
  AuthService._internal();

  Future<Map<String, dynamic>?> login(String email, String password) async {
    try {
      print('Login attempt with: $email'); // Debug log
      
      final response = await http.post(
        Uri.parse(ApiConfig.login),
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
        },
        body: jsonEncode({
          'email': email,
          'password': password,
        }),
      );

      print('Response status: ${response.statusCode}');
      print('Response body: ${response.body}');

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        await _saveAuthData(
          data['access_token'],
          data['user'],
        );
        final prefs = await SharedPreferences.getInstance();
        await prefs.setString('user_id', data['user']['id'].toString());
        return data;
      }

      final errorData = jsonDecode(response.body);
      throw Exception(errorData['message'] ?? errorData['error'] ?? 'Login failed');
    } catch (e) {
      print('Login error details: $e');
      if (e is HandshakeException) {
        throw Exception('Tidak dapat terhubung ke server. Pastikan server berjalan.');
      }
      rethrow;
    }
  }

  Future<void> logout() async {
    try {
      final token = await getToken();
      if (token != null) {
        await http.post(
          Uri.parse(ApiConfig.logout),
          headers: ApiConfig.authHeaders(token),
        );
      }
    } catch (e) {
      print('Logout error: $e');
    } finally {
      await _clearAuthData();
    }
  }

  Future<Map<String, dynamic>?> refreshToken() async {
    try {
      final token = await getToken();
      if (token == null) throw Exception('No token found');

      final response = await http.post(
        Uri.parse(ApiConfig.refresh),
        headers: ApiConfig.authHeaders(token),
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        await _saveAuthData(
          data['access_token'],
          data['user'],
        );
        return data;
      }
      throw Exception('Token refresh failed');
    } catch (e) {
      print('Refresh token error: $e');
      await _clearAuthData();
      rethrow;
    }
  }

  Future<void> _saveAuthData(
    String token,
    Map<String, dynamic> userData,
  ) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(tokenKey, token);
    await prefs.setString(userKey, jsonEncode(userData));
  }

  Future<void> _clearAuthData() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(tokenKey);
    await prefs.remove(userKey);
  }

  Future<String?> getToken() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(tokenKey);
  }

  Future<String?> getUserId() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString('user_id');
  }

  Future<Map<String, dynamic>?> getUserData() async {
    final prefs = await SharedPreferences.getInstance();
    final userStr = prefs.getString(userKey);
    if (userStr != null) {
      return jsonDecode(userStr);
    }
    return null;
  }

  Future<bool> isLoggedIn() async {
    final token = await getToken();
    return token != null;
  }

  Future<bool> checkSession(BuildContext context) async {
    final token = await getToken();
    if (token == null) {
      // Jika tidak ada token, arahkan ke halaman login
      Navigator.of(context).pushNamedAndRemoveUntil('/login', (route) => false);
      return false;
    }

    try {
      final response = await http.get(
        Uri.parse(ApiConfig.profile),
        headers: ApiConfig.authHeaders(token),
      );

      if (response.statusCode == 401) {
        // Token tidak valid atau expired
        await _clearAuthData();
        Navigator.of(context).pushNamedAndRemoveUntil('/login', (route) => false);
        return false;
      }

      return true;
    } catch (e) {
      print('Error checking session: $e');
      return false;
    }
  }

  Future<void> changePassword({
    required String currentPassword,
    required String newPassword,
    required String confirmPassword,
  }) async {
    try {
      final token = await getToken();
      if (token == null) {
        throw Exception('Token tidak ditemukan');
      }

      print('Attempting to change password...');
      print('Endpoint: ${ApiConfig.changePassword}');

      final response = await http.post(
        Uri.parse(ApiConfig.changePassword),
        headers: {
          'Authorization': 'Bearer $token',
          'Accept': 'application/json',
          'Content-Type': 'application/json',
        },
        body: jsonEncode({
          'current_password': currentPassword,
          'new_password': newPassword,
          'confirm_password': confirmPassword,
        }),
      );

      print('Response status: ${response.statusCode}');
      print('Response body: ${response.body}');

      if (response.statusCode == 200) {
        return;
      }

      final data = jsonDecode(response.body);
      if (data['errors'] != null) {
        final errors = data['errors'] as Map<String, dynamic>;
        final firstError = errors.values.first;
        if (firstError is List && firstError.isNotEmpty) {
          throw Exception(firstError[0]);
        }
        throw Exception(firstError.toString());
      }
      throw Exception(data['message'] ?? 'Gagal mengubah password');
    } catch (e) {
      print('Change password error: $e');
      if (e is SocketException) {
        throw Exception('Tidak dapat terhubung ke server. Periksa koneksi internet Anda.');
      }
      rethrow;
    }
  }
} 