import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../../core/network/api_client.dart';
import '../models/admin_driver.dart';
import '../models/admin_incident.dart';
import '../models/admin_route.dart';
import '../models/admin_unit.dart';
import '../models/admin_user.dart';

final adminServiceProvider = Provider<AdminService>((ref) {
  return AdminService(ref.read(apiClientProvider));
});

class AdminService {
  AdminService(this._dio);
  final Dio _dio;

  // ── Users ───────────────────────────────────────────────────────────────────
  Future<List<AdminUserModel>> listUsers() async {
    final res = await _dio.get<List<dynamic>>('/admin/users');
    return (res.data ?? [])
        .whereType<Map>()
        .map((e) => AdminUserModel.fromJson(Map<String, dynamic>.from(e)))
        .toList();
  }

  Future<AdminUserModel> createUser({
    required String name,
    required String password,
    String? email,
    String? phone,
    String role = 'citizen',
  }) async {
    final res = await _dio.post<Map<String, dynamic>>(
      '/admin/users',
      data: {
        'name': name,
        'password': password,
        if (email != null && email.isNotEmpty) 'email': email,
        if (phone != null && phone.isNotEmpty) 'phone': phone,
        'role': role,
      },
    );
    return AdminUserModel.fromJson(res.data!);
  }

  Future<AdminUserModel> updateUser(
    String id, {
    String? name,
    String? email,
    String? role,
  }) async {
    final res = await _dio.patch<Map<String, dynamic>>(
      '/admin/users/$id',
      data: {
        if (name != null) 'name': name,
        if (email != null) 'email': email,
        if (role != null) 'role': role,
      },
    );
    return AdminUserModel.fromJson(res.data!);
  }

  Future<void> deleteUser(String id) async {
    await _dio.delete<void>('/admin/users/$id');
  }

  // ── Routes ──────────────────────────────────────────────────────────────────
  Future<List<AdminRouteModel>> listRoutes() async {
    final res = await _dio.get<List<dynamic>>('/admin/routes');
    return (res.data ?? [])
        .whereType<Map>()
        .map((e) => AdminRouteModel.fromJson(Map<String, dynamic>.from(e)))
        .toList();
  }

  Future<AdminRouteModel> createRoute({
    required String id,
    String? name,
    int? truckId,
    String? turno,
    String? status,
  }) async {
    final res = await _dio.post<Map<String, dynamic>>(
      '/admin/routes',
      data: {
        'id': id,
        if (name != null) 'name': name,
        if (truckId != null) 'truck_id': truckId,
        if (turno != null) 'turno': turno,
        if (status != null) 'status': status,
      },
    );
    return AdminRouteModel.fromJson(res.data!);
  }

  Future<AdminRouteModel> updateRoute(
    String id, {
    String? name,
    int? truckId,
    String? turno,
    String? status,
  }) async {
    final res = await _dio.patch<Map<String, dynamic>>(
      '/admin/routes/$id',
      data: {
        if (name != null) 'name': name,
        if (truckId != null) 'truck_id': truckId,
        if (turno != null) 'turno': turno,
        if (status != null) 'status': status,
      },
    );
    return AdminRouteModel.fromJson(res.data!);
  }

  Future<void> deleteRoute(String id) async {
    await _dio.delete<void>('/admin/routes/$id');
  }

  // ── Units ───────────────────────────────────────────────────────────────────
  Future<List<AdminUnitModel>> listUnits() async {
    final res = await _dio.get<List<dynamic>>('/admin/units');
    return (res.data ?? [])
        .whereType<Map>()
        .map((e) => AdminUnitModel.fromJson(Map<String, dynamic>.from(e)))
        .toList();
  }

  Future<AdminUnitModel> createUnit({
    required int id,
    String? plate,
    String status = 'active',
  }) async {
    final res = await _dio.post<Map<String, dynamic>>(
      '/admin/units',
      data: {'id': id, if (plate != null) 'plate': plate, 'status': status},
    );
    return AdminUnitModel.fromJson(res.data!);
  }

  Future<AdminUnitModel> updateUnit(
    int id, {
    String? plate,
    String? status,
  }) async {
    final res = await _dio.patch<Map<String, dynamic>>(
      '/admin/units/$id',
      data: {
        if (plate != null) 'plate': plate,
        if (status != null) 'status': status,
      },
    );
    return AdminUnitModel.fromJson(res.data!);
  }

  Future<void> deleteUnit(int id) async {
    await _dio.delete<void>('/admin/units/$id');
  }

  // ── Drivers ─────────────────────────────────────────────────────────────────
  Future<List<AdminDriverModel>> listDrivers() async {
    final res = await _dio.get<List<dynamic>>('/admin/drivers');
    return (res.data ?? [])
        .whereType<Map>()
        .map((e) => AdminDriverModel.fromJson(Map<String, dynamic>.from(e)))
        .toList();
  }

  Future<AdminDriverModel> createDriver({
    required String userId,
    int? unitId,
  }) async {
    final res = await _dio.post<Map<String, dynamic>>(
      '/admin/drivers',
      data: {'user_id': userId, if (unitId != null) 'unit_id': unitId},
    );
    return AdminDriverModel.fromJson(res.data!);
  }

  Future<AdminDriverModel> updateDriver(String id, {int? unitId}) async {
    final res = await _dio.patch<Map<String, dynamic>>(
      '/admin/drivers/$id',
      data: {if (unitId != null) 'unit_id': unitId},
    );
    return AdminDriverModel.fromJson(res.data!);
  }

  Future<void> deleteDriver(String id) async {
    await _dio.delete<void>('/admin/drivers/$id');
  }

  // ── Incidents ────────────────────────────────────────────────────────────────
  Future<List<AdminIncidentModel>> listIncidentsByUnit(int unitId) async {
    final res = await _dio.get<List<dynamic>>('/admin/units/$unitId/incidents');
    return (res.data ?? [])
        .whereType<Map>()
        .map((e) => AdminIncidentModel.fromJson(Map<String, dynamic>.from(e)))
        .toList();
  }

  Future<AdminIncidentModel> createIncident({
    required int unitId,
    required String type,
    String? description,
  }) async {
    final res = await _dio.post<Map<String, dynamic>>(
      '/admin/units/$unitId/incidents',
      data: {
        'unit_id': unitId,
        'type': type,
        if (description != null && description.isNotEmpty)
          'description': description,
      },
    );
    return AdminIncidentModel.fromJson(res.data!);
  }

  // ── Simulación ──────────────────────────────────────────────────────────────
  /// Avanza una vez la simulación (`positionId += 1` en todas las rutas) y
  /// dispara los push FCM correspondientes. Devuelve los eventos disparados.
  Future<List<Map<String, dynamic>>> simulationTick() async {
    final res = await _dio.post<Map<String, dynamic>>('/simulation/tick');
    final events = (res.data?['events'] as List?) ?? const [];
    return events
        .whereType<Map>()
        .map((e) => Map<String, dynamic>.from(e))
        .toList();
  }
}
