import 'package:flutter/material.dart';
import 'package:tm_app/core/utils/result.dart';
import 'package:tm_app/data/services/model/feedback_stats/feedback_stats.dart';
import 'package:tm_app/data/services/model/recommended_tenders_response/recommended_tenders_response.dart';
import 'package:tm_app/data/services/model/tender_approvals_response/tender_approvals_response.dart';
import 'package:tm_app/data/services/model/tender_approvals_stats_response/tender_approvals_stats_response.dart';
import 'package:tm_app/data/services/model/tender_data/tender_data.dart';

import '../data/repositories/home_repository.dart';
import '../data/services/model/feedback_stats_response/feedback_stat_response.dart';
import '../data/services/model/home/home_response/home_response_model.dart';
import '../data/services/model/request_models/get_tenders_request_model/get_tenders_request_model.dart';

class HomeViewModel with ChangeNotifier {
  final HomeRepository _homeRepository;

  HomeViewModel({required HomeRepository homeRepository})
    : _homeRepository = homeRepository {
    init();
  }

  bool _isLoading = false;
  String? _errorMessage;
  HomeResponseModel? _homeResponse;
  TenderApprovalsResponse? data;

  bool get isLoading => _isLoading;
  String? get errorMessage => _errorMessage;
  HomeResponseModel? get homeResponse => _homeResponse;

  RecommendedTendersResponse? _recommendedTendersResponse;
  TenderApprovalsStatsResponse? tenderApprovalsStateResponse;
  FeedbackStats? feedbackStats;
  final List<TenderData> _tenders = [];
  final int _pageSize = 10;
  int _currentPage = 0;
  bool _isLoadingMore = false;
  bool _hasMore = true;

  bool _isRecommendedMode = false;

  List<TenderData> get tenders => _tenders;
  bool get isLoadingMore => _isLoadingMore;
  bool get hasMore => _hasMore;
  bool get isRecommendedMode => _isRecommendedMode;

  bool _hasUnreadNotification = false;
  bool get hasUnreadNotification => _hasUnreadNotification;

  void init() async {
    _isLoading = true;
    notifyListeners();

    await getApprovedStates();
    await getYourTenders(reset: true);
    await getFeedbackStats();
    await checkUnreadNotifications();

    if (_errorMessage != null) {
      _isLoading = false;
      notifyListeners();
      return;
    }
    _isLoading = false;
    notifyListeners();
  }

  Future<void> getHomeRecommendTenders({bool reset = false}) async {
    if (_isLoadingMore || (!_hasMore && !reset)) {
      return;
    }

    if (reset) {
      _currentPage = 0;
      _hasMore = true;
      _tenders.clear();
    }

    _isLoadingMore = true;
    _errorMessage = null;
    _isRecommendedMode = true;
    notifyListeners();

    final result = await _homeRepository.getHomeRecommendedTenders(
      limit: _pageSize,
      offset: _currentPage * _pageSize,
    );

    switch (result) {
      case Ok<RecommendedTendersResponse>():
        _recommendedTendersResponse = result.value;

        if (_recommendedTendersResponse?.data?.tenders.isNotEmpty ?? false) {
          _tenders.addAll(
            _recommendedTendersResponse!.data!.tenders.whereType<TenderData>(),
          );
          _currentPage++;
        } else {
          _hasMore = false;
        }
        break;

      case Error<RecommendedTendersResponse>():
        _errorMessage = result.error.toString();
        break;
    }

    _isLoadingMore = false;
    notifyListeners();
  }

  Future<void> getYourTenders({bool reset = false}) async {
    if (_isLoadingMore || (!_hasMore && !reset)) {
      return;
    }

    if (reset) {
      _currentPage = 0;
      _hasMore = true;
      _tenders.clear();
    }

    _isLoadingMore = true;
    _isRecommendedMode = false;
    notifyListeners();
    final requestModel = GetTendersRequestModel(
      limit: _pageSize,
      offset: _currentPage * _pageSize,
    );
    final result = await _homeRepository.getYourTenders(
      requestModel: requestModel,
    );

    switch (result) {
      case Ok<TenderApprovalsResponse>():
        data = result.value;

        final tendersList = data?.data?.tenders ?? [];
        final metadata = data?.data?.metadata;

        if (tendersList.isNotEmpty) {
          _tenders.addAll(
            tendersList.map((e) => e.tender).whereType<TenderData>(),
          );
          _currentPage++;

          if (metadata != null && (_currentPage >= metadata.pages!)) {
            _hasMore = false;
          }
        } else {
          _hasMore = false;
        }
        break;

      case Error<TenderApprovalsResponse>():
        _errorMessage = result.error.toString();
        break;
    }

    _isLoadingMore = false;
    notifyListeners();
  }

  Future<void> getApprovedStates() async {
    final result = await _homeRepository.getTendersApprovalsStats();

    switch (result) {
      case Ok<TenderApprovalsStatsResponse>():
        tenderApprovalsStateResponse = result.value;
        break;
      case Error<TenderApprovalsStatsResponse>():
        _errorMessage = result.error.toString();
        break;
    }
    notifyListeners();
  }

  Future<void> getFeedbackStats() async {
    final result = await _homeRepository.getFeedbackStats();

    switch (result) {
      case Ok<FeedbackStatResponse>():
        feedbackStats = result.value.data;
        break;
      case Error<FeedbackStatResponse>():
        _errorMessage = result.error.toString();
        break;
    }
    notifyListeners();
  }

  double get partnershipCount {
    return tenderApprovalsStateResponse?.data?.partnershipCount?.toDouble() ??
        0.0;
  }

  double get selfApplyCount {
    return tenderApprovalsStateResponse?.data?.selfApplyCount?.toDouble() ??
        0.0;
  }

  double get totalCount {
    return partnershipCount + selfApplyCount;
  }

  double get partnershipPercent {
    return totalCount > 0 ? (partnershipCount / totalCount) * 100 : 0;
  }

  double get selfApplyPercent {
    return totalCount > 0 ? (selfApplyCount / totalCount) * 100 : 0;
  }

  Future<void> checkUnreadNotifications() async {
    final result = await _homeRepository.checkUnreadNotifications();
    switch (result) {
      case Ok<Map<String, dynamic>>():
        final response = result.value;
        _hasUnreadNotification = response['success'] == true;
        break;
      case Error<Map<String, dynamic>>():
        _hasUnreadNotification = false;
        break; 
    }
    notifyListeners();
  }

  void serUnreadNotificationFalse(){
    _hasUnreadNotification = false;
    notifyListeners();
  
  }
}
