import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart';
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_automation_model.dart';
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart';
import 'package:syncrow_web/pages/routines/models/icon_model.dart';
import 'package:syncrow_web/pages/routines/models/routine_details_model.dart';
import 'package:syncrow_web/pages/routines/models/routine_model.dart';
import 'package:syncrow_web/services/api/api_exception.dart';
import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart';

class SceneApi {
  static final HTTPService _httpService = HTTPService();

// //create scene
  static Future<Map<String, dynamic>> createScene(
      CreateSceneModel createSceneModel) async {
    try {
      debugPrint('create scene model: ${createSceneModel.toMap()}');
      final response = await _httpService.post(
        path: ApiEndpoints.createScene,
        body: createSceneModel.toMap(),
        showServerMessage: false,
        expectedResponseModel: (json) {
          return json;
        },
      );
      debugPrint('create scene response: $response');
      return response;
    } on DioException catch (e) {
      String errorMessage =
          e.response?.data['error']['message'][0] ?? 'something went wrong';
      throw APIException(errorMessage);
    }
  }

//
// create automation
  static Future<Map<String, dynamic>> createAutomation(
      CreateAutomationModel createAutomationModel, String projectId) async {
    try {
      final response = await _httpService.post(
        path:
            ApiEndpoints.createAutomation.replaceAll('{projectId}', projectId),
        body: createAutomationModel.toMap(),
        showServerMessage: false,
        expectedResponseModel: (json) {
          return json;
        },
      );
      debugPrint('create automation response: $response');
      return response;
    } on DioException catch (e) {
      String errorMessage =
          e.response?.data['error']['message'][0] ?? 'something went wrong';
      throw APIException(errorMessage);
    }
  }

  static Future<List<IconModel>> getIcon() async {
    final response = await _httpService.get(
      path: ApiEndpoints.getIconScene,
      showServerMessage: false,
      expectedResponseModel: (json) {
        List<IconModel> iconsList = [];
        json.forEach((element) {
          iconsList.add(IconModel.fromJson(element));
        });
        return iconsList;
      },
    );
    return response;
  }

  //get scenes by community id and space id

  static Future<List<ScenesModel>> getScenes(
      String spaceId, String communityId, String projectId,
      {showInDevice = false}) async {
    try {
      final response = await _httpService.get(
        path: ApiEndpoints.getUnitScenes
            .replaceAll('{spaceUuid}', spaceId)
            .replaceAll('{communityUuid}', communityId)
            .replaceAll('{projectId}', projectId),
        queryParameters: {'showInHomePage': showInDevice},
        showServerMessage: false,
        expectedResponseModel: (json) {
          final scenesJson = json['data'] as List;

          List<ScenesModel> scenes = [];
          for (var scene in scenesJson) {
            scenes.add(ScenesModel.fromJson(scene, isAutomation: false));
          }
          return scenes;
        },
      );
      return response;
    } catch (e) {
      rethrow;
    }
  }

  //getAutomation

  static Future<List<ScenesModel>> getAutomation(
      String spaceId, String communityId, String projectId) async {
    try {
      final response = await _httpService.get(
        path: ApiEndpoints.getSpaceAutomation
            .replaceAll('{spaceUuid}', spaceId)
            .replaceAll('{communityId}', communityId)
            .replaceAll('{projectId}', projectId),
        showServerMessage: false,
        expectedResponseModel: (json) {
          List<ScenesModel> scenes = [];
          for (var scene in json) {
            scenes.add(ScenesModel.fromJson(scene, isAutomation: true));
          }
          return scenes;
        },
      );
      return response;
    } catch (e) {
      rethrow;
    }
  }

  // static Future<bool> triggerScene(String sceneId) async {
  //   try {
  //     final response = await _httpService.post(
  //       path: ApiEndpoints.triggerScene.replaceAll('{sceneId}', sceneId),
  //       showServerMessage: false,
  //       expectedResponseModel: (json) => json['success'],
  //     );
  //     return response;
  //   } catch (e) {
  //     rethrow;
  //   }
  // }

//automation details
  static Future<RoutineDetailsModel> getAutomationDetails(
      String automationId, String projectId) async {
    try {
      final response = await _httpService.get(
        path: ApiEndpoints.getAutomationDetails
            .replaceAll('{automationId}', automationId)
            .replaceAll('{projectId}', projectId),
        showServerMessage: false,
        expectedResponseModel: (json) => RoutineDetailsModel.fromMap(json),
      );
      return response;
    } catch (e) {
      rethrow;
    }
  }

  //update Scene
  static updateScene(CreateSceneModel createSceneModel, String sceneId) async {
    try {
      final response = await _httpService.put(
        path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId),
        body: createSceneModel
            .toJson(sceneId.isNotEmpty == true ? sceneId : null),
        expectedResponseModel: (json) {
          return json;
        },
      );
      return response;
    } on DioException catch (e) {
      String errorMessage =
          e.response?.data['error']['message'][0] ?? 'something went wrong';
      throw APIException(errorMessage);
    }
  }

  //update automation
  static updateAutomation(CreateAutomationModel createAutomationModel,
      String automationId, String projectId) async {
    try {
      final response = await _httpService.put(
        path: ApiEndpoints.updateAutomation
            .replaceAll('{automationId}', automationId)
            .replaceAll('{projectId}', projectId),
        body: createAutomationModel
            .toJson(automationId.isNotEmpty == true ? automationId : null),
        expectedResponseModel: (json) {
          return json;
        },
      );
      return response;
    } on DioException catch (e) {
      String errorMessage =
          e.response?.data['error']['message'][0] ?? 'something went wrong';
      throw APIException(errorMessage);
    }
  }

  //getScene
  static Future<RoutineDetailsModel> getSceneDetails(String sceneId) async {
    try {
      final response = await _httpService.get(
        path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId),
        showServerMessage: false,
        expectedResponseModel: (json) =>
            RoutineDetailsModel.fromMap(json['data']),
      );
      return response;
    } catch (e) {
      rethrow;
    }
  }

  //delete Scene
  static Future<bool> deleteScene(
      {required String unitUuid, required String sceneId}) async {
    try {
      final response = await _httpService.delete(
        path: ApiEndpoints.deleteScene
            .replaceAll('{sceneId}', sceneId)
            .replaceAll('{unitUuid}', unitUuid),
        showServerMessage: false,
        expectedResponseModel: (json) => json['statusCode'] == 200,
      );
      return response;
    } on DioException catch (e) {
      String errorMessage =
          e.response?.data['error']['message'][0] ?? 'something went wrong';
      throw APIException(errorMessage);
    }
  }

  // delete automation
  static Future<bool> deleteAutomation(
      {required String unitUuid,
      required String automationId,
      required String projectId}) async {
    try {
      final response = await _httpService.delete(
        path: ApiEndpoints.deleteAutomation
            .replaceAll('{automationId}', automationId)
            .replaceAll('{projectId}', projectId),
        showServerMessage: false,
        expectedResponseModel: (json) => json['statusCode'] == 200,
      );
      return response;
    } on DioException catch (e) {
      String errorMessage =
          e.response?.data['error']['message'][0] ?? 'something went wrong';
      throw APIException(errorMessage);
    }
  }

  static Future<bool> updateAutomationStatus(String automationId,
      AutomationStatusUpdate createAutomationEnable, String projectId) async {
    try {
      final response = await _httpService.patch(
        path: ApiEndpoints.updateAutomationStatus
            .replaceAll('{automationId}', automationId)
            .replaceAll('{projectId}', projectId),
        body: createAutomationEnable.toMap(),
        expectedResponseModel: (json) => json['success'],
      );
      return response;
    } catch (e) {
      rethrow;
    }
  }

  static Future<bool> triggerScene(String sceneId) async {
    try {
      final response = await _httpService.post(
        path: ApiEndpoints.triggerScene.replaceAll('{sceneId}', sceneId),
        showServerMessage: false,
        expectedResponseModel: (json) => json['success'],
      );
      return response;
    } catch (e) {
      rethrow;
    }
  }

  static Future<List<ScenesModel>> getAutomationByUnitId(
    String unitId,
    String communityId,
    String projectId,
  ) async {
    try {
      final response = await _httpService.get(
        path: ApiEndpoints.getUnitAutomation
            .replaceAll('{unitUuid}', unitId)
            .replaceAll('{communityId}', communityId)
            .replaceAll('{projectId}', projectId),
        showServerMessage: false,
        expectedResponseModel: (json) {
          List<ScenesModel> scenes = [];
          for (var scene in json) {
            scenes.add(ScenesModel.fromJson(scene));
          }
          return scenes;
        },
      );
      return response;
    } catch (e) {
      rethrow;
    }
  }
}
