import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/features/operations/data/operations_repository.dart';
import 'package:flux/features/operations/models/operation_model.dart';
import 'package:get_it/get_it.dart';

part 'operation_list_state.dart';

class OperationListCubit extends Cubit<OperationListState> {
  final OperationsRepository _repository = GetIt.I<OperationsRepository>();
  final SessionCubit _sessionCubit = GetIt.I<SessionCubit>();

  OperationListCubit() : super(const OperationListState());

  // 🥷 MOTORE 1: DESKTOP (Sostituisce la lista)
  Future<void> loadSpecificPageDesktop(int page) async {
    if (state.status == OperationListStatus.loading) return;
    emit(state.copyWith(status: OperationListStatus.loading));

    try {
      final companyId = _sessionCubit.state.company?.id;
      final paginatedData = await _repository.fetchPaginatedOperations(
        companyId: companyId!,
        page: page,
        itemsPerPage: state.itemsPerPage,
      );

      emit(
        state.copyWith(
          status: OperationListStatus.success,
          operations: paginatedData.operations, // 🎯 SOSTITUISCE I DATI
          totalItems: paginatedData.totalCount,
          currentPage: page,
          hasReachedMax: paginatedData.operations.length < state.itemsPerPage,
        ),
      );
    } catch (e) {
      emit(
        state.copyWith(
          status: OperationListStatus.failure,
          errorMessage: e.toString(),
        ),
      );
    }
  }

  // 🥷 MOTORE 2: MOBILE (Accoda alla lista)
  Future<void> loadNextPageMobile({bool refresh = false}) async {
    if (state.status == OperationListStatus.loading) return;
    if (state.hasReachedMax && !refresh) return;

    // Se stiamo pullando verso il basso (refresh), ripartiamo da pagina 1
    final targetPage = refresh ? 1 : state.currentPage + 1;

    // Mostriamo il loading solo se è un refresh totale, altrimenti manteniamo lo stato success
    // per non far sparire la UI mentre carica in fondo
    if (refresh) emit(state.copyWith(status: OperationListStatus.loading));

    try {
      final companyId = _sessionCubit.state.company?.id;
      final paginatedData = await _repository.fetchPaginatedOperations(
        companyId: companyId!,
        page: targetPage,
        itemsPerPage: state.itemsPerPage,
      );

      emit(
        state.copyWith(
          status: OperationListStatus.success,
          // 🎯 ACCODA I DATI SE NON È REFRESH, ALTRIMENTI SOSTITUISCE
          operations:
              refresh ? paginatedData.operations : List.of(state.operations)
                ..addAll(paginatedData.operations),
          totalItems: paginatedData.totalCount,
          currentPage: targetPage,
          hasReachedMax: paginatedData.operations.length < state.itemsPerPage,
        ),
      );
    } catch (e) {
      emit(
        state.copyWith(
          status: OperationListStatus.failure,
          errorMessage: e.toString(),
        ),
      );
    }
  }

  void updateFilters({String? text, DateTimeRange? range}) {
    emit(
      state.copyWith(
        // 🥷 FORZIAMO IL TIPO: Diciamo a Dart che il risultato del ternario è proprio una funzione
        searchTerm: text != null ? () => text : null,
        dateRange: range != null ? () => range : null,

        currentPage: 1, // Reset obbligatorio alla prima pagina
        hasReachedMax: false,
      ),
    );

    // Ricarichiamo la pagina 1 con i nuovi filtri applicati
    loadSpecificPageDesktop(1);
  }

  void clearFilters() {
    // Invece di un const vuoto che potrebbe bruciarti l'impostazione itemsPerPage,
    // creiamo uno stato pulito ma manteniamo la preferenza di paginazione.
    emit(OperationListState(itemsPerPage: state.itemsPerPage));

    loadSpecificPageDesktop(1);
  }
}
