import 'dart:convert';

import 'package:account/src/core/data/datasource/account_remote_datasource.dart';
import 'package:account/src/core/data/models/change_password_request_model.dart';
import 'package:account/src/core/data/models/get_app_users_response_model.dart';
import 'package:account/src/core/data/models/get_linked_devices_response_model.dart';
import 'package:account/src/core/data/models/update_device_request_model.dart';
import 'package:account/src/core/data/models/update_user_request_model.dart';
import 'package:account/src/features/change_password/domain/models/entities/change_password_request_entity.dart';
import 'package:legacy_shared/src/data/models/entities/device_entity.dart';
import 'package:account/src/features/linked_devices/domain/entities/update_device_request_entity.dart';
import 'package:account/src/features/personal_data/domain/entities/update_user_request_entity.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:dio/dio.dart';
// import 'package:flutter/material.dart';
import 'package:sf_infrastructure/sf_infrastructure.dart';

class AccountRemoteDatasourceImpl implements AccountRemoteDatasource {
  AccountRemoteDatasourceImpl(this._repository);

  final QuestiaRepository _repository;

  @override
  Future<List<DeviceEntity>> getLinkedDevices({required String userId}) async {
    try {
      /*final response = await _repository.get<Map<String, dynamic>>(
        '/$userId/devices',
      );
      final data = response.data!['items'];
      if (data == null || data.isEmpty) {
        throw Exception('Empty response from /:userId/devices');
      }

      final model = GetLinkedDevicesResponseModel.fromJson(data);*/
      final model = GetLinkedDevicesResponseModel(items: [
        GetLinkedDevicesItemResponseModel(
          identificator: '1111',
          carrierName: 'Carlos',
          phone: '111111111',
          id: '',
          settings: GetLinkedDevicesSettingsResponseModel(
            frequency: 0,
            frequencyHeartRate: 0,
            timezone: 0,
            pedometer: false,
            language: 'language',
            alerts: [],
          ),
          protocol: '',
          type: '',
          connectionServer: '',
          createdAt: 0,
          flags: GetLinkedDevicesFlagsResponseModel(
            isInOrOut: 'isInOrOut',
            geofenceId: 'geofenceId',
            isBatteryLow: false,
            isDisconnect: false,
          )
        ),
        GetLinkedDevicesItemResponseModel(
          identificator: '1112',
          carrierName: 'Ana',
          phone: '222222222',
          id: '',
          settings: GetLinkedDevicesSettingsResponseModel(
            frequency: 0,
            frequencyHeartRate: 0,
            timezone: 0,
            pedometer: false,
            language: 'language',
            alerts: [],
          ),
          protocol: '',
          type: '',
          connectionServer: '',
          createdAt: 0,
          flags: GetLinkedDevicesFlagsResponseModel(
            isInOrOut: 'isInOrOut',
            geofenceId: 'geofenceId',
            isBatteryLow: false,
            isDisconnect: false,
          )
        ),
      ]);
      return model.toEntity();
    } on DioException catch (error) {
      throw _mapDioError(
        error,
        defaultMessage: error.message ?? 'Error getting devices',
      );
    }
  }

  @override
  Future<void> deleteDevice({required String userId, required String deviceId}) async {
    try {
      await _repository.put<void>(
        '/users/$userId/devices/$deviceId',
      );
    } on DioException catch (error) {
      throw _mapDioError(error, defaultMessage: 'Error to delete device');
    }
  }

  @override
  Future<void> updateDevice({required String userId, required String deviceId, required UpdateDeviceRequestEntity request}) async {
    throw UnimplementedError();
    try {
      final body = request.toModel().toJson();
      await _repository.put<void>(
        '/users/$userId/devices/$deviceId',
        body: body,
      );
    } on DioException catch (error) {
      throw _mapDioError(error, defaultMessage: 'Error to update device');
    }
  }

  @override
  Future<void> updateUser({required String userId, required UpdateUserRequestEntity request}) async {
    try {
      final body = request.toModel().toJson();
      await _repository.put<void>(
        '/users/$userId',
        body: body,
      );
    } on DioException catch (error) {
      throw _mapDioError(error, defaultMessage: 'Error to update user');
    }
  }

  @override
  Future<List<UserEntity>> getAppUsers({required String userId}) async {
    try {
      final response = await _repository.get<Map<String, dynamic>>(
        '/$userId/devices',
      );
      final data = response.data!['items'];
      if (data == null || data.isEmpty) {
        throw Exception('Empty response from /:userId/devices');
      }

      final model = GetAppUsersResponseModel.fromJson(data);
      /*final model = GetAppUsersResponseModel(items: [
        GetAppUsersItemResponseModel(
          id: 'id',
          delegationId: 'delegationId',
          email: 'carlos@test.com',
          createdAt: 'createdAt',
          updatedAt: 'updatedAt',
          status: 'status',
          role: 'role',
          lastLogin: 'lastLogin',
          currentLogin: 'currentLogin',
          language: 'language',
          firstName: 'Carlos',
          lastName: 'lastName',
          hasApiKey: 'hasApiKey',
          phone: 'phone',),
        GetAppUsersItemResponseModel(
          id: 'id',
          delegationId: 'delegationId',
          email: 'ana@test.com',
          createdAt: 'createdAt',
          updatedAt: 'updatedAt',
          status: 'status',
          role: 'role',
          lastLogin: 'lastLogin',
          currentLogin: 'currentLogin',
          language: 'language',
          firstName: 'Ana',
          lastName: 'lastName',
          hasApiKey: 'hasApiKey',
          phone: 'phone',),
      ]);*/
      return model.toEntity();
    } on DioException catch (error) {
      throw _mapDioError(
        error,
        defaultMessage: error.message ?? 'Error getting devices',
      );
    }
  }

  @override
  Future<void> deleteAppUser({required String userId}) async {
    throw UnimplementedError();
    try {
      await _repository.delete<void>(
        '/users/$userId',
      );
    } on DioException catch (error) {
      throw _mapDioError(error, defaultMessage: 'Error to delete device');
    }
  }

  @override
  Future<void> changePassword({required String userId, required ChangePasswordRequestEntity request}) async {
    try {
      final body = request.toModel().toJson();
      await _repository.put<void>(
        '/auth/change-password',
        body: body,
      );
    } on DioException catch (error) {
      throw _mapDioError(error, defaultMessage: 'Error to change password');
    }
  }
}

Exception _mapDioError(DioException error, {required String defaultMessage}) {
  final apiMsg = _extractApiMessage(error.response?.data);
  final msg = apiMsg ?? error.message ?? defaultMessage;
  return Exception(msg);
}

String? _extractApiMessage(Object? data) {
  if (data == null) return null;

  if (data is Map) {
    final errorObj = data['error'];
    if (errorObj is Map && errorObj['message'] is String) {
      return (errorObj['message'] as String).trim();
    }
    if (data['message'] is String) {
      return (data['message'] as String).trim();
    }
    return null;
  }

  if (data is String) {
    final raw = data.trim();
    if (raw.isEmpty) return null;

    try {
      final decoded = jsonDecode(raw);
      return _extractApiMessage(decoded);
    } catch (_) {
      return raw;
    }
  }

  return null;
}
