import 'package:hmg_qline/api/api_client.dart';
import 'package:hmg_qline/constants/app_constants.dart';
import 'package:hmg_qline/models/generic_response_model.dart';
import 'package:hmg_qline/models/global_config_model.dart';
import 'package:hmg_qline/models/kiosk_ticket_model.dart';
import 'package:hmg_qline/models/prayers_widget_model.dart';
import 'package:hmg_qline/models/rss_feed_model.dart';
import 'package:hmg_qline/models/weathers_widget_model.dart';
import 'package:hmg_qline/services/logger_service.dart';
import 'package:hmg_qline/utilities/enums.dart';
import 'package:hmg_qline/utilities/extensions.dart';
import 'package:hmg_qline/views/view_helpers/info_components.dart';

abstract class ScreenDetailsRepo {
  Future<GlobalConfigurationsModel?> getGlobalScreenConfigurations({required String ipAddress});

  Future<GenericRespModel?> createTestTickets({required int ticketNumber});

  Future<GenericRespModel?> createTicketFromKiosk({required int projectId, required int queueId, int patientId = 0});

  Future<WeathersWidgetModel?> getWeatherDetailsByCity({required String cityId});

  Future<PrayersWidgetModel?> getPrayerDetailsByLatLong({required double latitude, required double longitude});

  Future<RssFeedModel?> getRssFeedDetailsByLanguageID({required int languageId});

  Future<GenericRespModel?> acknowledgeTicket({required String ipAddress, required int ticketQueueID, required QTypeEnum qTypeEnum});

  Future<GenericRespModel?> acknowledgeTicketForAppointment({required int ticketId, required String ipAddress, required CallTypeEnum callTypeEnum});
}

class ScreenDetailsRepoImp implements ScreenDetailsRepo {
  ApiClient apiClientInstance;
  LoggerService loggerService;

  ScreenDetailsRepoImp({required this.apiClientInstance, required this.loggerService});

  @override
  Future<GlobalConfigurationsModel?> getGlobalScreenConfigurations({required String ipAddress}) async {
    try {
      var params = {
        "ipAddress": ipAddress.toString(),
        "apiKey": AppConstants.apiKey.toString(),
      };
      GenericRespModel genericModel = await apiClientInstance.postJsonForObject(
        (json) => GenericRespModel.fromJson(json),
        ApiConstants.commonConfigGet,
        params,
      );
      List<GlobalConfigurationsModel> globalConfigurationsModel = List.generate(genericModel.data.length, (index) => GlobalConfigurationsModel.fromJson(json: genericModel.data[index]));
      if (globalConfigurationsModel.isNotEmpty) {
        loggerService.logToFile(message: globalConfigurationsModel.toString(), type: LogTypeEnum.data, source: "getGlobalScreenConfigurations-> screen_details_repo.dart");
        return globalConfigurationsModel.first;
      }
      return null;
    } catch (e) {
      loggerService.logError(e.toString());
      loggerService.logToFile(message: e.toString(), source: "getGlobalScreenConfigurations-> screen_details_repo.dart", type: LogTypeEnum.error);
      InfoComponents.showToast(e.toString());
      return null;
    }
  }

  @override
  Future<GenericRespModel?> createTestTickets({required int ticketNumber}) async {
    try {
      var params = {
        "projectID": "15",
        "patientID": ticketNumber.toString(),
        "isVip": false,
        "orderNo": "123",
        "isVidaPlus": false,
        "createdBy": "101",
        "apiKey": AppConstants.apiKey,
      };
      GenericRespModel genericModel = await apiClientInstance.postJsonForObject(
        (json) => GenericRespModel.fromJson(json),
        ApiConstants.createTicket,
        params,
      );
      return genericModel;
    } catch (e) {
      loggerService.logError(e.toString());
      loggerService.logToFile(message: e.toString(), source: "createTestTickets-> screen_details_repo.dart", type: LogTypeEnum.error);
      InfoComponents.showToast(e.toString());
      return null;
    }
  }

  @override
  Future<GenericRespModel?> createTicketFromKiosk({required int projectId, required int queueId, int patientId = 0}) async {
    try {
      var params = {
        "projectID": "$projectId",
        "queueID": "$queueId",
        "patientID": "$patientId",
        "isVidaPlus": false,
        "createdBy": "101",
        "apiKey": AppConstants.apiKey,
      };
      GenericRespModel genericRespModel = await apiClientInstance.postJsonForObject(
        (json) => GenericRespModel.fromJson(json),
        ApiConstants.createTicketForKiosk,
        params,
      );

      genericRespModel.data = KioskPatientTicket.fromJson(genericRespModel.data);
      loggerService.logToFile(message: genericRespModel.toString(), source: "createTicketFromKiosk-> screen_details_repo.dart", type: LogTypeEnum.data);

      return genericRespModel;
    } catch (e) {
      loggerService.logError(e.toString());
      loggerService.logToFile(message: e.toString(), source: "createTicketFromKiosk-> screen_details_repo.dart", type: LogTypeEnum.error);
      InfoComponents.showToast(e.toString());
      return null;
    }
  }

  @override
  Future<WeathersWidgetModel?> getWeatherDetailsByCity({required String cityId}) async {
    WeathersWidgetModel constantWeathersWidgetModel = WeathersWidgetModel(
      id: 12345,
      headline: "Hot and sunny conditions expected",
      maxTemp: 42.5,
      minTemp: 28.3,
      iconPhrase: "Mostly sunny",
      forecastDate: "2024-12-19",
      cityID: 287,
      forecastDay: "Thursday",
      createDateTime: "2024-12-19T08:30:00Z",
      windSpeed: 12.5,
      windDirection: "NW",
      windDegrees: 315.0,
      weatherIconPathRight: AppAssets.sunnyLeftIcon,
      weatherIconPathLeft: AppAssets.sunnyRightIcon,
    );
    try {
      final body = {"cityID": cityId};
      GenericRespModel genericRespModel = await apiClientInstance.postJsonForObject(
        (json) => GenericRespModel.fromJson(json),
        ApiConstants.getWeatherForecastBy5Days,
        body,
      );

      List<WeathersWidgetModel> weathersWidgetModel = List.generate(genericRespModel.data.length, (index) => WeathersWidgetModel.fromJson(genericRespModel.data[index]));
      if (weathersWidgetModel.isNotEmpty) {
        loggerService.logToFile(message: weathersWidgetModel.toString(), source: "getWeatherDetailsByCity-> screen_details_repo.dart", type: LogTypeEnum.data);
        return weathersWidgetModel.first;
      }
      return constantWeathersWidgetModel;
    } catch (e) {
      loggerService.logError(e.toString());
      loggerService.logToFile(message: e.toString(), source: "getWeatherDetailsByCity-> screen_details_repo.dart", type: LogTypeEnum.error);
      InfoComponents.showToast(e.toString());
      return constantWeathersWidgetModel;
    }
  }

  @override
  Future<PrayersWidgetModel?> getPrayerDetailsByLatLong({required double latitude, required double longitude}) async {
    try {
      final body = {"latitude": latitude, "longitude": longitude};
      GenericRespModel genericRespModel = await apiClientInstance.postJsonForObject(
        (json) => GenericRespModel.fromJson(json),
        ApiConstants.prayerTimeToday,
        body,
      );

      List<PrayersWidgetModel> prayersWidgetModel = List.generate(genericRespModel.data.length, (index) => PrayersWidgetModel.fromJson(genericRespModel.data[index]));
      if (prayersWidgetModel.isNotEmpty) {
        loggerService.logToFile(message: prayersWidgetModel.toString(), source: "getPrayerDetailsByLatLong-> screen_details_repo.dart", type: LogTypeEnum.data);
        return prayersWidgetModel.first;
      }

      return null;
    } catch (e) {
      loggerService.logError(e.toString());
      loggerService.logToFile(message: e.toString(), source: "getPrayerDetailsByLatLong-> screen_details_repo.dart", type: LogTypeEnum.error);
      InfoComponents.showToast(e.toString());
      return null;
    }
  }

  @override
  Future<RssFeedModel?> getRssFeedDetailsByLanguageID({required int languageId}) async {
    try {
      final body = {"languageID": languageId};
      GenericRespModel genericRespModel = await apiClientInstance.postJsonForObject(
        (json) => GenericRespModel.fromJson(json),
        ApiConstants.rssFeedGet,
        body,
      );

      List<RssFeedModel> rssFeedModel = List.generate(genericRespModel.data.length, (index) => RssFeedModel.fromJson(genericRespModel.data[index]));
      if (rssFeedModel.isNotEmpty) {
        loggerService.logToFile(message: rssFeedModel.toString(), source: "getRssFeedDetailsByLanguageID-> screen_details_repo.dart", type: LogTypeEnum.data);

        return rssFeedModel.first;
      }
      return null;
    } catch (e) {
      loggerService.logError(e.toString());
      loggerService.logToFile(message: e.toString(), source: "getRssFeedDetailsByLanguageID-> screen_details_repo.dart", type: LogTypeEnum.error);
      InfoComponents.showToast(e.toString());
      return null;
    }
  }

  @override
  Future<GenericRespModel?> acknowledgeTicket({required String ipAddress, required int ticketQueueID, required QTypeEnum qTypeEnum}) async {
    try {
      var params = {
        "ipAddress": ipAddress.toString(),
        "ticketQueueID": ticketQueueID.toString(),
        "qType": qTypeEnum.getQTypeIDFromEnum().toString(),
      };
      GenericRespModel genericModel = await apiClientInstance.postJsonForObject(
        (json) => GenericRespModel.fromJson(json),
        ApiConstants.ticketAcknowledgementInsert,
        params,
      );
      return genericModel;
    } catch (e) {
      loggerService.logError(e.toString());
      loggerService.logToFile(message: e.toString(), source: "acknowledgeTicket-> screen_details_repo.dart", type: LogTypeEnum.error);
      InfoComponents.showToast(e.toString());
      return null;
    }
  }

  @override
  Future<GenericRespModel?> acknowledgeTicketForAppointment({required int ticketId, required String ipAddress, required CallTypeEnum callTypeEnum}) async {
    try {
      var params = {
        "id": ticketId.toString(),
        "apiKey": AppConstants.apiKey,
        "ipAddress": ipAddress,
        "callType": callTypeEnum.getIdFromCallTypeEnum().toString(),
      };

      GenericRespModel genericModel = await apiClientInstance.postJsonForObject(
        (json) => GenericRespModel.fromJson(json),
        ApiConstants.ticketCallRequestUpdate,
        params,
      );
      return genericModel;
    } catch (e) {
      loggerService.logError(e.toString());
      loggerService.logToFile(message: e.toString(), source: "acknowledgeTicketForAppointment-> screen_details_repo.dart", type: LogTypeEnum.error);
      InfoComponents.showToast(e.toString());
      return null;
    }
  }
}
