import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/foundation.dart' show kIsWeb;

class AbsensiApi {
  static const String baseUrl = 'https://ta.myhost.id/E31230906/api';

  static const String absenMasukEndpoint    = '/absensi/absen-masuk';
  static const String absenKeluarEndpoint   = '/absensi/absen-keluar';
  static const String checkStatusEndpoint   = '/absensi/check-status';
  static const String riwayatEndpoint       = '/absensi/riwayat';
  static const String kalenderEndpoint      = '/absensi/kalender';
  static const String rekapEndpoint         = '/absensi/rekap';
  static const Duration timeoutDuration     = Duration(seconds: 30);

  Future<String?> _getToken() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      return prefs.getString('access_token');
    } catch (e) {
      print('Error getting token: $e');
      return null;
    }
  }

  Future<Map<String, String>> _getMultipartHeaders() async {
    final token = await _getToken();
    return {
      'Accept': 'application/json',
      if (token != null) 'Authorization': 'Bearer $token',
    };
  }

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

  /// Absen masuk dengan support Web & Mobile
  Future<Map<String, dynamic>> absenMasuk({
    required int idTeknisi,
    XFile? fotoAbsenMasuk,
    String? status,
    String? keterangan,
    double? latitude,
    double? longitude,
  }) async {
    try {
      print('=== ABSEN MASUK REQUEST ===');
      print('ID Teknisi: $idTeknisi');
      print('Status: ${status ?? "null"}');
      print('Keterangan: ${keterangan ?? "null"}');
      print('Foto: ${fotoAbsenMasuk != null ? "Ada (${fotoAbsenMasuk.name})" : "TIDAK ADA"}');

      var request = http.MultipartRequest(
        'POST',
        Uri.parse('$baseUrl$absenMasukEndpoint'),
      );

      request.headers.addAll(await _getMultipartHeaders());
      request.fields['id_teknisi'] = idTeknisi.toString();

      if (status != null && status.isNotEmpty) {
        request.fields['status'] = status;
      }

      if (keterangan != null && keterangan.isNotEmpty) {
        request.fields['keterangan'] = keterangan;
      }

      if (latitude != null) {
        request.fields['latitude'] = latitude.toString();
      }

      if (longitude != null) {
        request.fields['longitude'] = longitude.toString();
      }

      if (fotoAbsenMasuk != null) {
        if (kIsWeb) {
          final bytes = await fotoAbsenMasuk.readAsBytes();
          print('📸 Foto size (Web): ${bytes.length} bytes');
          request.files.add(http.MultipartFile.fromBytes(
            'foto_absen_masuk', bytes,
            filename: fotoAbsenMasuk.name,
          ));
        } else {
          print('📸 Foto path (Mobile): ${fotoAbsenMasuk.path}');
          request.files.add(await http.MultipartFile.fromPath(
            'foto_absen_masuk', fotoAbsenMasuk.path,
          ));
        }
      }

      print('📤 Sending request to: $baseUrl$absenMasukEndpoint');
      final streamedResponse = await request.send().timeout(timeoutDuration);
      final response = await http.Response.fromStream(streamedResponse);

      print('=== ABSEN MASUK RESPONSE ===');
      print('Status Code: ${response.statusCode}');
      print('Response Body: ${response.body}');

      final data = jsonDecode(response.body);

      if (response.statusCode == 201 && data['success'] == true) {
        print('✅ ABSEN MASUK SUKSES!');
        return {'success': true, 'message': data['message'], 'data': data['data']};
      } else if (response.statusCode == 400) {
        print('❌ Error 400: ${data['message']}');
        return {'success': false,
            'message': data['message'] ?? 'Anda sudah melakukan absen masuk hari ini'};
      } else if (response.statusCode == 422) {
        print('❌ Validation Error: ${data['errors']}');
        String errorMessage = 'Validasi gagal';
        if (data['errors'] != null) {
          final errors = data['errors'] as Map<String, dynamic>;
          errorMessage = errors.values.first[0];
        }
        return {'success': false, 'message': errorMessage, 'errors': data['errors']};
      } else {
        print('❌ Unknown Error: ${response.statusCode}');
        return {'success': false,
            'message': data['message'] ?? 'Gagal melakukan absen masuk'};
      }
    } catch (e, stackTrace) {
      print('❌ EXCEPTION di absenMasuk: $e');
      print(stackTrace);
      return {'success': false, 'message': 'Terjadi kesalahan: ${e.toString()}'};
    }
  }

  /// Absen keluar dengan support Web & Mobile
  Future<Map<String, dynamic>> absenKeluar({
    required int idTeknisi,
    XFile? fotoAbsenKeluar,
    String? status,
    String? keterangan,
    double? latitude,
    double? longitude,
  }) async {
    try {
      print('=== ABSEN KELUAR REQUEST ===');
      print('ID Teknisi: $idTeknisi');
      print('Status: ${status ?? "null"}');
      print('Keterangan: ${keterangan ?? "null"}');
      print('Foto: ${fotoAbsenKeluar != null ? "Ada (${fotoAbsenKeluar.name})" : "TIDAK ADA"}');

      var request = http.MultipartRequest(
        'POST',
        Uri.parse('$baseUrl$absenKeluarEndpoint'),
      );

      request.headers.addAll(await _getMultipartHeaders());
      request.fields['id_teknisi'] = idTeknisi.toString();

      if (status != null && status.isNotEmpty) {
        request.fields['status'] = status;
      }

      if (keterangan != null && keterangan.isNotEmpty) {
        request.fields['keterangan'] = keterangan;
      }

      if (latitude != null) {
        request.fields['latitude'] = latitude.toString();
      }

      if (longitude != null) {
        request.fields['longitude'] = longitude.toString();
      }

      if (fotoAbsenKeluar != null) {
        if (kIsWeb) {
          final bytes = await fotoAbsenKeluar.readAsBytes();
          print('📸 Foto size (Web): ${bytes.length} bytes');
          request.files.add(http.MultipartFile.fromBytes(
            'foto_absen_keluar', bytes,
            filename: fotoAbsenKeluar.name,
          ));
        } else {
          print('📸 Foto path (Mobile): ${fotoAbsenKeluar.path}');
          request.files.add(await http.MultipartFile.fromPath(
            'foto_absen_keluar', fotoAbsenKeluar.path,
          ));
        }
      }

      print('📤 Sending request to: $baseUrl$absenKeluarEndpoint');
      final streamedResponse = await request.send().timeout(timeoutDuration);
      final response = await http.Response.fromStream(streamedResponse);

      print('=== ABSEN KELUAR RESPONSE ===');
      print('Status Code: ${response.statusCode}');
      print('Response Body: ${response.body}');

      final data = jsonDecode(response.body);

      if (response.statusCode == 200 && data['success'] == true) {
        print('✅ ABSEN KELUAR SUKSES!');
        return {'success': true, 'message': data['message'], 'data': data['data']};
      } else if (response.statusCode == 400) {
        print('❌ Error 400: ${data['message']}');
        return {'success': false,
            'message': data['message'] ?? 'Belum melakukan absen masuk atau sudah absen keluar'};
      } else if (response.statusCode == 422) {
        print('❌ Validation Error: ${data['errors']}');
        String errorMessage = 'Validasi gagal';
        if (data['errors'] != null) {
          final errors = data['errors'] as Map<String, dynamic>;
          errorMessage = errors.values.first[0];
        }
        return {'success': false, 'message': errorMessage, 'errors': data['errors']};
      } else {
        print('❌ Unknown Error: ${response.statusCode}');
        return {'success': false,
            'message': data['message'] ?? 'Gagal melakukan absen keluar'};
      }
    } catch (e, stackTrace) {
      print('❌ EXCEPTION di absenKeluar: $e');
      print(stackTrace);
      return {'success': false, 'message': 'Terjadi kesalahan: ${e.toString()}'};
    }
  }

  /// Cek status absensi hari ini
  Future<Map<String, dynamic>> checkStatus(int idTeknisi) async {
    try {
      final token = await _getToken();
      final response = await http.get(
        Uri.parse('$baseUrl$checkStatusEndpoint/$idTeknisi'),
        headers: {
          'Accept': 'application/json',
          if (token != null) 'Authorization': 'Bearer $token',
        },
      ).timeout(timeoutDuration);

      final data = jsonDecode(response.body);

      if (response.statusCode == 200 && data['success'] == true) {
        return {'success': true, 'message': data['message'], 'data': data['data']};
      } else if (response.statusCode == 404) {
        return {'success': false, 'message': 'Teknisi tidak ditemukan'};
      } else {
        return {'success': false,
            'message': data['message'] ?? 'Gagal mengecek status absensi'};
      }
    } catch (e) {
      return {'success': false, 'message': 'Terjadi kesalahan: ${e.toString()}'};
    }
  }

  // ── Method baru ────────────────────────────────────────────────────────────

  /// Ambil riwayat absensi per bulan
  /// Endpoint: GET /api/absensi/riwayat?id_teknisi=1&bulan=3&tahun=2026
  Future<Map<String, dynamic>> getRiwayat({
    required int idTeknisi,
    required int bulan,
    required int tahun,
  }) async {
    try {
      final url = Uri.parse(
          '$baseUrl$riwayatEndpoint?id_teknisi=$idTeknisi&bulan=$bulan&tahun=$tahun');
      print('📋 GET Riwayat: $url');

      final response = await http.get(url,
          headers: await _getHeaders()).timeout(timeoutDuration);

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

      final data = jsonDecode(response.body);

      if (response.statusCode == 200 && data['success'] == true) {
        return {'success': true, 'data': data['data'] ?? []};
      }
      return {
        'success': false,
        'message': data['message'] ?? 'Gagal memuat riwayat',
        'data': [],
      };
    } catch (e) {
      print('❌ getRiwayat error: $e');
      return {'success': false, 'message': e.toString(), 'data': []};
    }
  }

  /// Ambil status absensi per tanggal dalam 1 bulan (untuk kalender)
  /// Endpoint: GET /api/absensi/kalender?id_teknisi=1&bulan=3&tahun=2026
  /// Response data: { "1": "hadir", "5": "izin", "10": "alpha", ... }
  Future<Map<String, dynamic>> getKalender({
    required int idTeknisi,
    required int bulan,
    required int tahun,
  }) async {
    try {
      final url = Uri.parse(
          '$baseUrl$kalenderEndpoint?id_teknisi=$idTeknisi&bulan=$bulan&tahun=$tahun');
      print('📅 GET Kalender: $url');

      final response = await http.get(url,
          headers: await _getHeaders()).timeout(timeoutDuration);

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

      final data = jsonDecode(response.body);

      if (response.statusCode == 200 && data['success'] == true) {
        return {'success': true, 'data': data['data'] ?? {}};
      }
      return {
        'success': false,
        'message': data['message'] ?? 'Gagal memuat kalender',
        'data': {},
      };
    } catch (e) {
      print('❌ getKalender error: $e');
      return {'success': false, 'message': e.toString(), 'data': {}};
    }
  }

  /// Ambil rekap absensi bulanan
  /// Endpoint: GET /api/absensi/rekap?id_teknisi=1&bulan=3&tahun=2026
  /// Response data: { "bulan": "Maret 2026", "hadir": 14, "izin": 1, ... }
  Future<Map<String, dynamic>> getRekap({
    required int idTeknisi,
    required int bulan,
    required int tahun,
  }) async {
    try {
      final url = Uri.parse(
          '$baseUrl$rekapEndpoint?id_teknisi=$idTeknisi&bulan=$bulan&tahun=$tahun');
      print('📊 GET Rekap: $url');

      final response = await http.get(url,
          headers: await _getHeaders()).timeout(timeoutDuration);

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

      final data = jsonDecode(response.body);

      if (response.statusCode == 200 && data['success'] == true) {
        return {'success': true, 'data': data['data'] ?? {}};
      }
      return {
        'success': false,
        'message': data['message'] ?? 'Gagal memuat rekap',
        'data': {},
      };
    } catch (e) {
      print('❌ getRekap error: $e');
      return {'success': false, 'message': e.toString(), 'data': {}};
    }
  }
}