// ДЗ: Функциональное Объектно-Ориентированное программирование
// задание 1 Конструктор лица
{
  function Person(name, surname) {
    this.name = name;
    this.surname = surname;
    this.getFullName = function () {
      return `${this.name} ${this.surname}`;
    };
  }
}

{
  // пример использования:
  const a = new Person('Вася', 'Пупкин');
  console.log(a.getFullName()); // Вася Пупкин
  a.fatherName = 'Иванович';
  console.log(a.getFullName()); // Вася Иванович Пупкин

  const b = new Person('Анна', 'Иванова');
  console.log(b.getFullName()); // Анна Иванова

  const c = new Person('Елизавета', 'Петрова');
  console.log(c.getFullName()); // Елизавета Петрова
}

// задание 2 Прототип человека
{
  function Person(name, surname) {
    this.name = name;
    this.surname = surname;
  }

  Person.prototype.getFullName = function () {
    return `${this.name} ${this.surname}`;
  };
}

{
  // использование:
  const a = new Person('Вася', 'Пупкин');
  console.log(a.getFullName()); // Вася Пупкин
  a.fatherName = 'Иванович';
  console.log(a.getFullName()); // Вася Иванович Пупкин

  const b = new Person('Анна', 'Иванова');
  console.log(b.getFullName()); // Анна Иванова

  const c = new Person('Елизавета', 'Петрова');
  console.log(c.getFullName()); // Елизавета Петрова
}

// задание 3 Магазин
{
  function Store(reducer, state) {
    this.state = state;
    this.cbs = [];

    this.dispatch = (action) => {
      this.state = reducer(this.state, action);
      this.cbs.forEach((cb) => cb());
    };

    this.getState = () => this.state;

    this.subscribe = (cb) => {
      this.cbs.push(cb);
      return () => (this.cbs = this.cbs.filter((c) => c !== cb));
    };
  }
}

{
  const reducer = (state, action) => {
    // обработка action и возврат нового состояния
    return newState;
  };

  const store = new Store(reducer, {});

  store.subscribe(() => {
    console.log('State changed:', store.getState());
  });

  store.dispatch({ type: 'INCREMENT' }); // State changed: { count: 1 }
  store.dispatch({ type: 'DECREMENT' }); // State changed: { count: 0 }
}

// задание 4 Пароль
{
  function Password(parent, open) {
    this.input = document.createElement('input');
    this.input.type = open ? 'text' : 'password';
    this.input.addEventListener('input', () => this.onChange(this.input.value));

    this.checkbox = document.createElement('input');
    this.checkbox.type = 'checkbox';
    this.checkbox.checked = open;
    this.checkbox.addEventListener('change', () => this.setOpen(this.checkbox.checked));

    parent.append(this.input, this.checkbox);

    this.setValue = (value) => {
      this.input.value = value;
    };

    this.getValue = () => this.input.value;

    this.setOpen = (open) => {
      this.input.type = open ? 'text' : 'password';
      this.checkbox.checked = open;
      this.onOpenChange(open);
    };

    this.getOpen = () => this.checkbox.checked;
  }
}

// задание 5 ЛогинФорма
{
  const loginForm = document.createElement('form');

  const loginInput = document.createElement('input');
  loginInput.type = 'text';
  loginInput.placeholder = 'Логин';
  loginForm.append(loginInput);

  const password = new Password(loginForm, false);
  password.onChange = () => (loginButton.disabled = !(loginInput.value && password.getValue()));

  const loginButton = document.createElement('button');
  loginButton.textContent = 'Войти';
  loginButton.disabled = true;
  loginForm.append(loginButton);

  document.body.append(loginForm);
}

// задание 6 Конструктор формы входа
{
  function LoginForm(parent) {
    this.form = document.createElement('form');

    this.loginInput = document.createElement('input');
    this.loginInput.type = 'text';
    this.loginInput.placeholder = 'Логин';
    this.form.append(this.loginInput);

    this.password = new Password(this.form, false);
    this.password.onChange = () => this.updateButtonState();

    this.button = document.createElement('button');
    this.button.textContent = 'Войти';
    this.button.disabled = true;
    this.form.append(this.button);

    parent.append(this.form);

    this.setLogin = (login) => {
      this.loginInput.value = login;
      this.updateButtonState();
    };

    this.getLogin = () => this.loginInput.value;

    this.setPassword = (password) => {
      this.password.setValue(password);
      this.updateButtonState();
    };

    this.getPassword = () => this.password.getValue();

    this.updateButtonState = () => {
      this.button.disabled = !(this.loginInput.value && this.password.getValue());
    };

    this.onSubmit = () => {};

    this.form.addEventListener('submit', (event) => {
      event.preventDefault();
      this.onSubmit();
    });
  }
}

// задание 7 Подтвердить пароль
{
  function PasswordChecker(parent) {
    this.form = document.createElement('form');

    this.password1 = new Password(this.form, false);
    this.password1.onChange = () => this.updateValidity();
    this.form.append(this.password1.form);

    this.password2 = new Password(this.form, false);
    this.password2.onChange = () => this.updateValidity();
    this.form.append(this.password2.form);

    parent.append(this.form);

    this.updateValidity = () => {
      const isValid = this.password1.getValue() === this.password2.getValue();
      this.password1.form.classList.toggle('invalid', !isValid);
      this.password2.form.classList.toggle('invalid', !isValid);
    };

    this.password1.onOpenChange = (isOpen) => {
      if (isOpen) {
        this.password2.form.style.display = 'none';
      } else {
        this.password2.form.style.display = 'block';
      }
    };
  }
}
