// Backend API endpoints:
//   POST /auth/login              body: {"username":"...","secret":"..."}
//                                 → {"access_token":"...","token_type":"bearer"}
//   GET  /groups/my               header: Authorization: Bearer TOKEN
//                                 → [{"id":"uuid","name":"...","type":"...","is_active":true}]
//   POST /groups/                 body: {"name":"..."}
//                                 → GroupResponse
//   GET  /groups/{id}/members     → [{"user_id":"...","username":"...","role":"...","is_online":bool}]
//   POST /groups/{id}/invite      body: {"username":"..."}
//                                 → {"message":"...","notification_id":"..."}
//   DELETE /groups/{id}/members/{user_id}  → {"message":"..."}
//   GET  /notifications/          → [NotificationResponse]
//   POST /notifications/{id}/respond  body: {"is_accepted":bool}
//
// LiveKit token از طریق WebSocket دریافت می‌شود:
//   WS   /ws/groups/{id}?token={jwt}

import 'dart:convert';
import 'package:http/http.dart' as http;
import '../config/app_config.dart';
import '../models/channel.dart';
import '../models/group_member.dart';
import '../models/app_notification.dart';
import 'auth_service.dart';

// ── Fake data (only used when AppConfig.debug == true) ────────────────────
const _fakeChannels = [
  {'id': '1', 'name': 'تیم آلفا', 'type': 'PUBLIC', 'is_active': true},
  {'id': '2', 'name': 'پشتیبانی میدانی', 'type': 'PRIVATE', 'is_active': true},
  {'id': '3', 'name': 'فرماندهی', 'type': 'PUBLIC', 'is_active': true},
  {'id': '4', 'name': 'گروه لجستیک', 'type': 'PRIVATE', 'is_active': true},
  {'id': '5', 'name': 'واحد امنیت', 'type': 'PUBLIC', 'is_active': true},
];
// ─────────────────────────────────────────────────────────────────────────

class ApiService {
  final AuthService _auth;

  ApiService(this._auth);

  Future<Map<String, String>> _headers() async {
    final token = await _auth.getToken();
    return {
      'Content-Type': 'application/json',
      if (token != null) 'Authorization': 'Bearer $token',
    };
  }

  // استخراج user_id از JWT token (بدون نیاز به کتابخانه)
  String? _extractUserIdFromJwt(String token) {
    try {
      final parts = token.split('.');
      if (parts.length < 2) return null;
      var payload = parts[1];
      while (payload.length % 4 != 0) {
        payload += '=';
      }
      final decoded = utf8.decode(base64Url.decode(payload));
      final map = jsonDecode(decoded) as Map<String, dynamic>;
      return map['sub']?.toString();
    } catch (_) {
      return null;
    }
  }

  // ── Auth ──────────────────────────────────────────────────────────────

  Future<bool> login(String username, String secret) async {
    if (AppConfig.debug) {
      await Future.delayed(const Duration(milliseconds: 600));
      await _auth.saveAuth(token: 'debug_jwt', userId: 'debug_user');
      return true;
    }

    try {
      final res = await http
          .post(
            Uri.parse('${AppConfig.baseUrl}/auth/login'),
            headers: {'Content-Type': 'application/json'},
            body: jsonEncode({'username': username, 'secret': secret}),
          )
          .timeout(const Duration(seconds: 10));

      if (res.statusCode == 200) {
        final data = jsonDecode(res.body) as Map<String, dynamic>;
        final accessToken = data['access_token'] as String?;
        if (accessToken == null) return false;
        final userId = _extractUserIdFromJwt(accessToken);
        await _auth.saveAuth(token: accessToken, userId: userId);
        return true;
      }
      return false;
    } catch (_) {
      return false;
    }
  }

  // ── Groups ────────────────────────────────────────────────────────────

  Future<List<Channel>> getChannels() async {
    if (AppConfig.debug) {
      await Future.delayed(const Duration(milliseconds: 500));
      return _fakeChannels
          .map((e) => Channel.fromJson(e as Map<String, dynamic>))
          .toList();
    }

    try {
      final res = await http
          .get(
            Uri.parse('${AppConfig.baseUrl}/groups/my'),
            headers: await _headers(),
          )
          .timeout(const Duration(seconds: 10));

      if (res.statusCode == 200) {
        final list = jsonDecode(res.body) as List;
        return list
            .map((e) => Channel.fromJson(e as Map<String, dynamic>))
            .toList();
      }
      return [];
    } catch (_) {
      return [];
    }
  }

  Future<Channel?> createGroup(String name) async {
    if (AppConfig.debug) {
      await Future.delayed(const Duration(milliseconds: 400));
      return Channel(
        id: 'fake_${DateTime.now().millisecondsSinceEpoch}',
        name: name,
      );
    }

    try {
      final res = await http
          .post(
            Uri.parse('${AppConfig.baseUrl}/groups/'),
            headers: await _headers(),
            body: jsonEncode({'name': name}),
          )
          .timeout(const Duration(seconds: 10));

      if (res.statusCode == 200 || res.statusCode == 201) {
        final data = jsonDecode(res.body) as Map<String, dynamic>;
        return Channel.fromJson(data);
      }
      return null;
    } catch (_) {
      return null;
    }
  }

  Future<List<GroupMember>> getGroupMembers(String groupId) async {
    if (AppConfig.debug) {
      await Future.delayed(const Duration(milliseconds: 400));
      return [
        const GroupMember(
          userId: 'u1',
          username: 'علی',
          role: 'MANAGER',
          isOnline: true,
        ),
        const GroupMember(
          userId: 'u2',
          username: 'رضا',
          role: 'MEMBER',
          isOnline: false,
        ),
        const GroupMember(
          userId: 'u3',
          username: 'مریم',
          role: 'MEMBER',
          isOnline: true,
        ),
      ];
    }

    try {
      final res = await http
          .get(
            Uri.parse('${AppConfig.baseUrl}/groups/$groupId/members'),
            headers: await _headers(),
          )
          .timeout(const Duration(seconds: 10));

      if (res.statusCode == 200) {
        final list = jsonDecode(res.body) as List;
        return list
            .map((e) => GroupMember.fromJson(e as Map<String, dynamic>))
            .toList();
      }
      return [];
    } catch (_) {
      return [];
    }
  }

  Future<String?> inviteMember(String groupId, String username) async {
    if (AppConfig.debug) {
      await Future.delayed(const Duration(milliseconds: 400));
      return null; // success
    }

    try {
      final res = await http
          .post(
            Uri.parse('${AppConfig.baseUrl}/groups/$groupId/invite'),
            headers: await _headers(),
            body: jsonEncode({'username': username}),
          )
          .timeout(const Duration(seconds: 10));

      if (res.statusCode == 200 || res.statusCode == 201) {
        return null; // success, no error
      }
      // برگرداندن پیام خطا از بکند
      try {
        final data = jsonDecode(res.body) as Map<String, dynamic>;
        return (data['detail'] as String?) ?? 'خطا در ارسال دعوت';
      } catch (_) {
        return 'خطا در ارسال دعوت';
      }
    } catch (_) {
      return 'خطا در اتصال به سرور';
    }
  }

  Future<String?> removeMember(String groupId, String userId) async {
    if (AppConfig.debug) {
      await Future.delayed(const Duration(milliseconds: 400));
      return null;
    }

    try {
      final res = await http
          .delete(
            Uri.parse('${AppConfig.baseUrl}/groups/$groupId/members/$userId'),
            headers: await _headers(),
          )
          .timeout(const Duration(seconds: 10));

      if (res.statusCode == 200) return null;
      try {
        final data = jsonDecode(res.body) as Map<String, dynamic>;
        return (data['detail'] as String?) ?? 'خطا در حذف عضو';
      } catch (_) {
        return 'خطا در حذف عضو';
      }
    } catch (_) {
      return 'خطا در اتصال به سرور';
    }
  }

  // ── Notifications ─────────────────────────────────────────────────────

  Future<List<AppNotification>> getNotifications() async {
    if (AppConfig.debug) {
      await Future.delayed(const Duration(milliseconds: 400));
      return [
        AppNotification(
          id: 'n1',
          title: 'دعوت به گروه',
          description: 'شما به گروه "تیم آلفا" دعوت شده‌اید',
          type: 'JOIN_REQUEST',
          groupId: '1',
          isAccepted: null,
          receiverId: 'debug_user',
          senderId: 'u1',
        ),
        AppNotification(
          id: 'n2',
          title: 'اطلاعیه سیستم',
          description: 'سیستم به‌روزرسانی شد',
          type: 'PUBLIC',
          isAccepted: null,
          receiverId: 'debug_user',
        ),
      ];
    }

    try {
      final res = await http
          .get(
            Uri.parse('${AppConfig.baseUrl}/notifications/'),
            headers: await _headers(),
          )
          .timeout(const Duration(seconds: 10));

      if (res.statusCode == 200) {
        final list = jsonDecode(res.body) as List;
        print(list);
        return list
            .map((e) => AppNotification.fromJson(e as Map<String, dynamic>))
            .toList();
      }
      return [];
    } catch (_) {
      return [];
    }
  }

  Future<String?> respondToNotification(
    String notificationId,
    bool isAccepted,
  ) async {
    if (AppConfig.debug) {
      await Future.delayed(const Duration(milliseconds: 400));
      return null;
    }

    try {
      final res = await http
          .post(
            Uri.parse(
              '${AppConfig.baseUrl}/notifications/$notificationId/respond',
            ),
            headers: await _headers(),
            body: jsonEncode({'is_accepted': isAccepted}),
          )
          .timeout(const Duration(seconds: 10));

      if (res.statusCode == 200) return null;
      try {
        final data = jsonDecode(res.body) as Map<String, dynamic>;
        return (data['detail'] as String?) ?? 'خطا در پاسخ به اعلان';
      } catch (_) {
        return 'خطا در پاسخ به اعلان';
      }
    } catch (_) {
      return 'خطا در اتصال به سرور';
    }
  }
}
