import 'package:flutter/material.dart';
import 'package:prosapp_web_app/models/service.dart';
import 'package:prosapp_web_app/models/service_status.dart';
import 'package:prosapp_web_app/models/servicio_profesional.dart';
import 'package:prosapp_web_app/models/pro_state.dart';
import 'package:prosapp_web_app/models/usuario.dart';
import 'package:prosapp_web_app/services/api_service.dart';

class ServicesProvider extends ChangeNotifier {
  List<ServicioProfesional> services = [];
  ServicioProfesional? service;
  bool isLoading = true;
  final _api = ApiService.instance;

  void logout() {
    services = [];
    service = null;
    isLoading = false;
    notifyListeners();
  }

  Future<void> changeServiceStatus(String serviceId, ServiceStatus newStatus) async {
    try {
      await _api.patch('/services/$serviceId/status', {'status': enumToIntService(newStatus)});
      notifyListeners();
    } catch (e) {
      print('Error al actualizar el estado: $e');
    }
  }

  Future<void> changeUserScored(String serviceId) async {
    try {
      await _api.patch('/services/$serviceId/status', {'user_scored': true});
      notifyListeners();
    } catch (e) {
      print('Error al actualizar user_scored: $e');
    }
  }

  Future<void> changeProfessionalScored(String serviceId) async {
    try {
      await _api.patch('/services/$serviceId/status', {'professional_scored': true});
      notifyListeners();
    } catch (e) {
      print('Error al actualizar professional_scored: $e');
    }
  }

  void clearServices() {
    services.clear();
    notifyListeners();
  }

  getServiceForUser(String serviceId) async {
    try {
      isLoading = true;
      final data = await _api.get('/services/$serviceId');
      final map = data as Map<String, dynamic>;
      final servicio = Service.fromJson(map, map['id'] as String);
      final userData = await _api.get('/users/${servicio.professionalId}');
      final user = Usuario.fromDocument(userData as Map<String, dynamic>);
      service = ServicioProfesional(user: user, service: servicio);
    } catch (e) {
      service = null;
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }

  getServiceForProfessional(String serviceId) async {
    try {
      isLoading = true;
      final data = await _api.get('/services/$serviceId');
      final map = data as Map<String, dynamic>;
      final servicio = Service.fromJson(map, map['id'] as String);
      final userData = await _api.get('/users/${servicio.userId}');
      final user = Usuario.fromDocument(userData as Map<String, dynamic>);
      service = ServicioProfesional(user: user, service: servicio);
    } catch (e) {
      service = null;
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }

  getServicesForUser(String userId) async => _loadServices('/services/me', forUser: true);

  getServicesRequestsForProfessional(String userId) async => _loadServices('/services/professional/requests', forUser: false);

  getServicesForProfessional(String userId) async => _loadServices('/services/professional', forUser: false);

  getServicesHistoryForUser(String userId) async => _loadServices('/services/me/history', forUser: true);

  getServicesHistoryForProfessional(String userId) async => _loadServices('/services/professional/history', forUser: false);

  Future<void> _loadServices(String path, {required bool forUser}) async {
    try {
      isLoading = true;
      final res = await _api.get(path);
      // All service endpoints return {data:[...], meta:{...}}
      final data = (res is Map ? res['data'] : res) as List;

      services = data.map((e) {
        final m = e as Map<String, dynamic>;
        final servicio = Service.fromJson(m, m['id'] as String);
        // User data is embedded in the response to avoid extra calls
        // forUser=true: professional's user is in m['professionals']['users']
        // forUser=false: client's user is in m['users']
        Map<String, dynamic>? userDoc;
        if (forUser) {
          final prof = m['professionals'] as Map<String, dynamic>?;
          userDoc = prof?['users'] as Map<String, dynamic>?;
        } else {
          userDoc = m['users'] as Map<String, dynamic>?;
        }
        final user = userDoc != null
            ? Usuario.fromDocument(userDoc)
            : Usuario(id: '', email: null, phone: null, name: '?', nickname: null,
                city: null, picture: null, birthday: null, gender: null,
                proState: ProState.inactive, token: null);
        return ServicioProfesional(user: user, service: servicio);
      }).toList()
        ..sort((a, b) {
          try {
            final dateA = DateTime.parse(a.service.day);
            final dateB = DateTime.parse(b.service.day);
            if (dateA != dateB) return dateA.compareTo(dateB);
          } catch (_) {}
          final tA = a.service.range1Hour1.hour * 60 + a.service.range1Hour1.minute;
          final tB = b.service.range1Hour1.hour * 60 + b.service.range1Hour1.minute;
          return tA.compareTo(tB);
        });
    } catch (e) {
      print('Error obteniendo servicios: $e');
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }
}
