import 'package:flutter/material.dart';

import 'package:pshared/provider/account.dart';

import 'package:pweb/models/edit_state.dart';
import 'package:pshared/api/responses/error/server.dart';
import 'package:pweb/models/password_field_type.dart';
import 'package:pweb/models/visibility.dart';


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

  final Map<PasswordFieldType, VisibilityState> _visibility = {
    PasswordFieldType.old: VisibilityState.hidden,
    PasswordFieldType.newPassword: VisibilityState.hidden,
    PasswordFieldType.confirmPassword: VisibilityState.hidden,
  };
  EditState _state = EditState.view;
  String _errorText = '';
  bool _disposed = false;

  bool get isExpanded => _state != EditState.view;
  bool get isSaving => _state == EditState.saving;
  String get errorText => _errorText;
  EditState get state => _state;
  bool isPasswordVisible(PasswordFieldType type) =>
      _visibility[type] == VisibilityState.visible;

  void toggleExpanded() {
    if (_state == EditState.saving) return;
    _setState(_state == EditState.view ? EditState.edit : EditState.view);
    _setError('');
  }

  void togglePasswordVisibility(PasswordFieldType type) {
    final current = _visibility[type];
    if (current == null) return;
    _visibility[type] = current == 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(EditState.saving);
    _setError('');

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

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

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

  void _setState(EditState value) {
    if (_state == value || _disposed) return;
    _state = value;
    notifyListeners();
  }

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

  @override
  void dispose() {
    _disposed = true;
    oldPasswordController.dispose();
    newPasswordController.dispose();
    confirmPasswordController.dispose();
    super.dispose();
  }
}
