import 'package:flutter/material.dart';
import 'package:tm_app/core/utils/result.dart';
import 'package:tm_app/data/repositories/liked_tenders_repository.dart';
import 'package:tm_app/data/repositories/tenders_repository.dart';
import 'package:tm_app/data/services/model/liked_tender_feedback/liked_tender_feedback.dart';
import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_response.dart';
import 'package:tm_app/view_models/home_view_model.dart';

import '../data/services/model/feedback_response/feedback_response.dart';
import '../data/services/model/request_models/tender_feedback_request_model/tender_feedback_request_model.dart';

class LikedTendersViewModel with ChangeNotifier {
  final LikedTendersRepository _likedTendersRepository;
  final TendersRepository _tendersRepository;
  final HomeViewModel _homeViewModel;
  LikedTendersViewModel({
    required LikedTendersRepository likedTendersRepository,
    required TendersRepository tendersRepository,
    required HomeViewModel homeViewModel,
  }) : _likedTendersRepository = likedTendersRepository,
       _homeViewModel = homeViewModel,
       _tendersRepository = tendersRepository;

  bool isLoading = false;
  bool isLoadingMore = false;
  bool hasMore = true;
  String? errorMessage;
  LikedTendersResponse? data;

  int _offset = 0;
  final int _limit = 7;

  int currentPage = 1;

  // Approval status properties
  bool approvalStatus = false;
  final String _status = '';
  String? _errorMessage;
  final bool _isSubmitApprovalLoading = false;
  final bool _isRejectApprovalLoading = false;

  String get status => _status;
  String? get approvalErrorMessage => _errorMessage;
  bool get isSubmitApprovalLoading => _isSubmitApprovalLoading;
  bool get isRejectApprovalLoading => _isRejectApprovalLoading;

  void updateHome() {
    _homeViewModel.init();
  }

  void clearApprovalErrorMessage() {
    _errorMessage = null;
    notifyListeners();
  }

  Future<void> getLikedTenders({bool reset = false}) async {
    if (!reset && (isLoadingMore || !hasMore)) {
      return;
    }

    if (reset) {
      _offset = (currentPage - 1) * _limit;
      hasMore = true;

      data = null;
      isLoading = true;
      notifyListeners();
    } else {
      if (_offset == 0) {
        isLoading = true;
      } else {
        isLoadingMore = true;
      }
      notifyListeners();
    }

    errorMessage = null;

    final requestModel = TenderFeedbackRequestModel(
      offset: _offset,
      limit: _limit,
      feedbackType: 'like',
    );

    final result = await _likedTendersRepository.getLikedTenders(
      requestModel: requestModel,
    );

    switch (result) {
      case Ok<LikedTendersResponse>():
        final incoming = result.value;
        final incomingList = incoming.data?.feedback ?? [];

        if (reset) {
          data = incoming;
        } else {
          final existingList = data?.data?.feedback ?? [];
          final combined = List<LikedTenderFeedback>.of(existingList)
            ..addAll(incomingList);

          data = data?.copyWith(
            data: data?.data?.copyWith(
              feedback: combined,
              meta: incoming.data?.meta ?? data!.data!.meta,
            ),
          );
        }

        hasMore = incomingList.length == _limit;
        _offset += _limit;

        errorMessage = null;
        break;

      case Error<LikedTendersResponse>():
        errorMessage = result.error.toString();
        break;
    }

    isLoading = false;
    isLoadingMore = false;
    notifyListeners();
  }

  Future<void> loadMoreIfNeeded() async {
    if (isLoadingMore || !hasMore) {
      return;
    }
    await getLikedTenders(reset: false);
  }

  Future<void> jumpToPage(int page) async {
    currentPage = page;
    _offset = (page - 1) * _limit;
    hasMore = true;
    await getLikedTenders(reset: true);
  }

  void removeTenderById(String id) async {
    final current = data;
    final list = current?.data?.feedback;
    if (current == null || list == null) {
      return;
    }

    // Store original list to restore if error occurs
    final originalList = List<LikedTenderFeedback>.of(list);
    final updatedList = List<LikedTenderFeedback>.of(list)
      ..removeWhere((e) => e.tenderId == id);

    // Temporarily update UI
    data = current.copyWith(
      data: current.data?.copyWith(feedback: updatedList),
    );
    notifyListeners();

    final result = await _tendersRepository.toggleFeedback(
      tenderId: id,
      feedbackType: 'like',
    );

    switch (result) {
      case Ok<FeedbackResponse>():
        final updatedMeta = current.data?.meta?.copyWith(
          total: updatedList.length,
        );
        data = current.copyWith(
          data: current.data?.copyWith(
            feedback: updatedList,
            meta: updatedMeta,
          ),
        );
        break;
      case Error<FeedbackResponse>():
        // Restore original list if error occurs
        data = current.copyWith(
          data: current.data?.copyWith(feedback: originalList),
        );
        errorMessage = result.error.toString();
        break;
    }

    notifyListeners();
  }
}
