import 'package:flutter/foundation.dart';
import 'package:superport_v2/core/common/models/paginated_result.dart';
import 'package:superport_v2/core/network/failure.dart';

import '../../domain/entities/customer.dart';
import '../../domain/repositories/customer_repository.dart';

/// 고객 유형 필터 옵션.
enum CustomerTypeFilter { all, partner, general }

/// 고객 활성 상태 필터 옵션.
enum CustomerStatusFilter { all, activeOnly, inactiveOnly }

/// 고객 목록 조회/등록/수정을 담당하는 프레젠테이션 컨트롤러.
class CustomerController extends ChangeNotifier {
  static const int defaultPageSize = 20;

  CustomerController({required CustomerRepository repository})
    : _repository = repository;

  final CustomerRepository _repository;

  PaginatedResult<Customer>? _result;
  bool _isLoading = false;
  bool _isSubmitting = false;
  String _query = '';
  CustomerTypeFilter _typeFilter = CustomerTypeFilter.all;
  CustomerStatusFilter _statusFilter = CustomerStatusFilter.all;
  int _pageSize = defaultPageSize;
  String? _errorMessage;

  PaginatedResult<Customer>? get result => _result;
  bool get isLoading => _isLoading;
  bool get isSubmitting => _isSubmitting;
  String get query => _query;
  CustomerTypeFilter get typeFilter => _typeFilter;
  CustomerStatusFilter get statusFilter => _statusFilter;
  int get pageSize => _pageSize;
  String? get errorMessage => _errorMessage;

  /// 고객 목록을 조회한다. 필터/페이지 상태는 내부에서 유지된다.
  Future<void> fetch({int page = 1}) async {
    _isLoading = true;
    _errorMessage = null;
    notifyListeners();
    try {
      final previous = _result;
      final int resolvedPage;
      if (page < 1) {
        resolvedPage = 1;
      } else if (previous != null && previous.pageSize > 0) {
        final calculated = (previous.total / previous.pageSize).ceil();
        final maxPage = calculated < 1 ? 1 : calculated;
        resolvedPage = page > maxPage ? maxPage : page;
      } else {
        resolvedPage = page;
      }
      bool? isPartner;
      bool? isGeneral;
      switch (_typeFilter) {
        case CustomerTypeFilter.all:
          isPartner = null;
          isGeneral = null;
          break;
        case CustomerTypeFilter.partner:
          isPartner = true;
          isGeneral = null;
          break;
        case CustomerTypeFilter.general:
          isPartner = null;
          isGeneral = true;
          break;
      }

      final isActive = switch (_statusFilter) {
        CustomerStatusFilter.all => null,
        CustomerStatusFilter.activeOnly => true,
        CustomerStatusFilter.inactiveOnly => false,
      };

      final response = await _repository.list(
        page: resolvedPage,
        pageSize: _pageSize,
        query: _query.isEmpty ? null : _query,
        isPartner: isPartner,
        isGeneral: isGeneral,
        isActive: isActive,
      );
      _result = response;
      if (response.pageSize > 0 && response.pageSize != _pageSize) {
        _pageSize = response.pageSize;
      }
    } catch (error) {
      final failure = Failure.from(error);
      _errorMessage = failure.describe();
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 검색어를 변경한다.
  void updateQuery(String value) {
    if (_query == value) {
      return;
    }
    _query = value;
    notifyListeners();
  }

  /// 고객 유형 필터를 변경한다.
  void updateTypeFilter(CustomerTypeFilter filter) {
    if (_typeFilter == filter) {
      return;
    }
    _typeFilter = filter;
    notifyListeners();
  }

  /// 고객 활성 상태 필터를 변경한다.
  void updateStatusFilter(CustomerStatusFilter filter) {
    if (_statusFilter == filter) {
      return;
    }
    _statusFilter = filter;
    notifyListeners();
  }

  /// 페이지 크기를 변경한다.
  void updatePageSize(int size) {
    if (size <= 0 || _pageSize == size) {
      return;
    }
    _pageSize = size;
    notifyListeners();
  }

  /// 신규 고객을 생성한다.
  Future<Customer?> create(CustomerInput input) async {
    _setSubmitting(true);
    try {
      final created = await _repository.create(input);
      await fetch(page: 1);
      return created;
    } catch (error) {
      final failure = Failure.from(error);
      _errorMessage = failure.describe();
      notifyListeners();
      return null;
    } finally {
      _setSubmitting(false);
    }
  }

  /// 기존 고객을 수정한다.
  Future<Customer?> update(int id, CustomerInput input) async {
    _setSubmitting(true);
    try {
      final updated = await _repository.update(id, input);
      await fetch(page: _result?.page ?? 1);
      return updated;
    } catch (error) {
      final failure = Failure.from(error);
      _errorMessage = failure.describe();
      notifyListeners();
      return null;
    } finally {
      _setSubmitting(false);
    }
  }

  /// 고객을 삭제한다.
  Future<bool> delete(int id) async {
    _setSubmitting(true);
    try {
      await _repository.delete(id);
      await fetch(page: _result?.page ?? 1);
      return true;
    } catch (error) {
      final failure = Failure.from(error);
      _errorMessage = failure.describe();
      notifyListeners();
      return false;
    } finally {
      _setSubmitting(false);
    }
  }

  /// 삭제된 고객을 복구한다.
  Future<Customer?> restore(int id) async {
    _setSubmitting(true);
    try {
      final restored = await _repository.restore(id);
      await fetch(page: _result?.page ?? 1);
      return restored;
    } catch (error) {
      final failure = Failure.from(error);
      _errorMessage = failure.describe();
      notifyListeners();
      return null;
    } finally {
      _setSubmitting(false);
    }
  }

  /// 에러 메시지를 초기화한다.
  void clearError() {
    _errorMessage = null;
    notifyListeners();
  }

  void _setSubmitting(bool value) {
    _isSubmitting = value;
    notifyListeners();
  }
}
