import 'package:flutter/material.dart';

import 'package:pshared/provider/account.dart';
import 'package:pshared/api/responses/error/server.dart';

import 'package:pweb/models/state/controller_lifecycle.dart';
import 'package:pweb/models/state/control_state.dart';
import 'package:pweb/models/state/visibility.dart';


class PasswordFormController extends ChangeNotifier {
  final formKey = GlobalKey<FormState>();
  final oldPasswordController = TextEditingController();
  final newPasswordController = TextEditingController();
  final confirmPasswordController = TextEditingController();

  ControlState _formState = ControlState.enabled;
  String _errorText = '';
  VisibilityState _oldPasswordVisibility = VisibilityState.hidden;
  ControllerLifecycleState _lifecycleState = ControllerLifecycleState.active;

  bool get isSaving => _formState == ControlState.loading;
  String get errorText => _errorText;
  VisibilityState get oldPasswordVisibility => _oldPasswordVisibility;

  void toggleOldPasswordVisibility() {
    _oldPasswordVisibility = _oldPasswordVisibility == VisibilityState.hidden
        ? VisibilityState.visible
        : VisibilityState.hidden;
    notifyListeners();
  }

  Future<bool> submit({
    required AccountProvider accountProvider,
    required String errorText,
  }) async {
    final currentForm = formKey.currentState;
    if (currentForm == null || !currentForm.validate()) return false;

    _setState(ControlState.loading);
    _setError('');

    try {
      await accountProvider.changePassword(
        oldPasswordController.text,
        newPasswordController.text,
      );

      oldPasswordController.clear();
      newPasswordController.clear();
      confirmPasswordController.clear();
      _setState(ControlState.enabled);
      return true;
    } catch (e) {
      _setError(_errorMessageForException(e, errorText));
      _setState(ControlState.enabled);
      rethrow;
    }
  }

  String _errorMessageForException(Object exception, String fallback) {
    if (exception is ErrorResponse && exception.details.isNotEmpty) {
      return exception.details;
    }
    return fallback;
  }

  void _setState(ControlState value) {
    if (_formState == value || _isDisposed) return;
    _formState = value;
    notifyListeners();
  }

  void _setError(String value) {
    if (_isDisposed) return;
    _errorText = value;
    notifyListeners();
  }

  bool get _isDisposed => _lifecycleState == ControllerLifecycleState.disposed;

  @override
  void dispose() {
    _lifecycleState = ControllerLifecycleState.disposed;
    oldPasswordController.dispose();
    newPasswordController.dispose();
    confirmPasswordController.dispose();
    super.dispose();
  }
}
