import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:road24_mobile/data/default_image.dart';
import 'package:road24_mobile/data/repository/CarsRepository.dart';
import 'package:road24_mobile/data/repository/UploadFileRepository.dart';
import 'package:road24_mobile/data/response/CarsResponse.dart';
import 'package:road24_mobile/data/response/FileUploadResponse.dart';
import 'package:road24_mobile/model/models/AddCarModel.dart';
import 'package:road24_mobile/my_app.dart';
import 'package:road24_mobile/utils/extensions.dart';

import 'package:intl/intl.dart';
part 'cars_event.dart';

part 'cars_state.dart';

class CarsBloc extends Bloc<CarsEvent, CarsState> {
  final CarsRepository repository;
  final UploadFileRepository fileRepository = UploadFileRepository();

  CarsBloc({required this.repository}) : super(CarsInitial());

  @override
  Stream<CarsState> mapEventToState(
    CarsEvent event,
  ) async* {
    if (event is GetCars) {
      try {
        yield CarsInitial();
        final response = await repository.getCars();
        if (response != null) {
          var carsResponse = CarsResponse.fromJson(response);

          carsResponse = carsResponse.copyWith(
              results: await _getConvertList(carsResponse.results));

          yield CarListSuccessState(response: carsResponse);
        } else
          MyApp.hasInternet.value = false;
      } catch (e) {
        print("exception in get cars ${e.toString()}");
        yield CarsLoadingError(exception: e);
      }
    } else if (event is GetCarDetails) {
      try {
        yield CarsInitial();

        final dynamic response =
            await repository.getCarDetailsByID(id: event.id);

        var val = CarDetailsResponse.fromJson(response);

        yield GetCarDetailsSuccessState(
          response: val,
        );
      } catch (e) {
        yield CarsLoadingError(exception: e);
      }
    } else if (event is AddCar) {
      try {
        yield CarsInitial();
        if (event.filePath != null) {
          final res = await fileRepository.uploadFile(
            event.filePath!,
            event.fileName,
          );
          final file = FileUploadResponse.fromJson(res?.data);
          AddCarModel.imageId = file.id;
        }
        await repository.addCar();
        yield AddCarSuccessState();
      } catch (exception) {
        yield CarsLoadingError(exception: exception);
      }
    } else if (event is EditCar) {
      try {
        yield CarsInitial();
        if (event.filePath != null) {
          print("file upload is begun");
          final res = await fileRepository.uploadFile(
            event.filePath!,
            event.fileName,
          );
          print("file from json ${res.data}");
          final file = FileUploadResponse.fromJson(res.data);
          print("after from json");
          AddCarModel.imageId = file.id;
        }
        await repository.editCar(event.id);
        yield EditCarSuccessState();
      } catch (e) {
        yield CarsLoadingError(exception: e);
      }
    } else if (event is EditCarConfidant) {
      try {
        yield CarsInitial();
        // final dynamic response =
        await repository.editCarConfidant(event.id);
        yield EditCarSuccessState();
      } catch (e) {
        yield CarsLoadingError(exception: e);
      }
    } else if (event is EditCarInspection) {
      try {
        yield CarsInitial();
        // final dynamic response =
        await repository.editCarInspection(event.id);
        yield EditCarSuccessState();
      } catch (e) {
        yield CarsLoadingError(exception: e);
      }
    } else if (event is EditCarInsurance) {
      try {
        yield CarsInitial();
        // final dynamic response =
        await repository.editCarInsurance(event.id);
        yield EditCarSuccessState();
      } catch (e) {
        yield CarsLoadingError(exception: e);
      }
    } else if (event is EditCarTinting) {
      try {
        yield CarsInitial();
        // final dynamic response =
        await repository.editCarTinting(event.id);
        yield EditCarSuccessState();
      } catch (e) {
        yield CarsLoadingError(exception: e);
      }
    } else if (event is EditCarOil) {
      try {
        yield CarsInitial();

        var model = event.model;

        var lastReplacement = event.lastReplaceDate;

        var nextMileageInDays = model.oilMileage! / model.dailyMileage!;

        event.model.lastReplacement =
            DateFormat('yyyy-MM-dd').format(lastReplacement);

        var nextReplacement =
            lastReplacement.add(Duration(days: nextMileageInDays.toInt()));

        print("oil mile ${event.model.oilMileage}");

        print("current mileage ${event.model.mileage}");

        event.model.nextMileage =
            event.model.oilMileage! + event.model.mileage!;

        event.model.nextReplacement =
            DateFormat('yyyy-MM-dd').format(nextReplacement);

        print("next replacement ${event.model.nextReplacement}}");
        print("next mileage ${event.model.nextMileage}}");

        // final dynamic response =
        await repository.editCarOil(event.id, event.model);

        yield EditCarSuccessState();
      } catch (e) {
        print("error in oil $e");
        yield CarsLoadingError(exception: e);
      }
    } else if (event is OilCalculateNextDate) {
      try {
        yield CarsInitial();

        var lastReplacement = event.lastOilDate;

        var nextMileageInDays = event.oilInterval / event.dailyMileage;

        var nextReplacementDateTime =
            lastReplacement.add(Duration(days: nextMileageInDays.toInt()));

        var nextMileage = event.oilInterval + event.mileage;

        var nextReplacement = nextReplacementDateTime.dateToStr();

        yield OilNextReplaceCalculated(nextMileage, nextReplacement);
      } catch (e) {
        yield CarsLoadingError(exception: e);
      }
    } else if (event is DeleteCar) {
      try {
        yield CarsInitial();
        // final dynamic response =
        await repository.deleteCar(event.id);
        yield DeleteCarSuccessState();
      } catch (e) {
        yield CarsLoadingError(exception: e);
      }
    } else if (event is CheckCarExistence) {
      try {
        yield CarsInitial();
        // final dynamic response =
        var techSery = event.techNumber.substring(0, 3);

        var techNumber = event.techNumber.substring(3);

        var result = await repository.checkCarExistence(
            event.plateNumber, techNumber, techSery);
        var isExist = result["isExist"];
        print("result...$isExist");
        yield CarExistResult(isExist);
      } catch (e) {
        print("error...$e");
        yield CarsLoadingError(exception: e);
      }
    } else if (event is GetCarOilList) {
      try {
        yield CarsInitial();
        // final dynamic response =
        var result = await repository.oilList(event.carDetailId);

        yield OilListResult(result);
      } catch (e) {
        print("error...$e");
        yield CarsLoadingError(exception: e);
      }
    }
  }

  Future<List<Results>> _getConvertList(List<Results> list) async {
    for (int i = 0; i < list.length; i++) {
      if (list[i].image == null) {
        if (list[i].carModel == null)
          list[i].carModel = CarModel(
            id: -1,
            carBrand: -1,
            name: 'model',
            image: DefaultImages.modelImage(list[i].model),
          );
        if (list[i].carBrand == null)
          list[i].carBrand = CarBrand(
            id: -1,
            name: 'brand',
            logo: DefaultImages.brandImage(list[i].brand),
          );
      }
    }
    return list;
  }
}
