package ru.vyatsu.qr_access_admin.door.component;

import ru.vyatsu.qr_access_admin.door.entity.DoorEntity;
import ru.vyatsu.qr_access_admin.unit.model.UnitComboBoxModel;
import ru.vyatsu.qr_access_admin.unit.entity.UnitRepository;
import ru.vyatsu.qr_access_admin.unit.mapper.UnitEntityUnitComboBoxModelMapper;
import com.vaadin.flow.component.Composite;
import com.vaadin.flow.component.Key;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.Binder;
import lombok.Getter;
import lombok.Setter;

import java.util.Map;
import java.util.stream.Collectors;

public class DoorEditor extends Composite<VerticalLayout> {

    private final UnitEntityUnitComboBoxModelMapper unitMapper = new UnitEntityUnitComboBoxModelMapper();

    public interface SaveListener {
        void onSave(DoorEntity door);
    }

    public interface DeleteListener {
        void onDelete(DoorEntity door);
    }

    public interface CancelListener {
        void onCancel();
    }

    private volatile DoorEntity currentDoor;

    @Getter
    @Setter
    private SaveListener saveListener;
    @Getter
    @Setter
    private DeleteListener deleteListener;
    @Getter
    @Setter
    private CancelListener cancelListener;

    private final Binder<DoorEntity> binder = new BeanValidationBinder<>(DoorEntity.class);

    public void setCurrentDoor(DoorEntity door) {
        this.currentDoor = door;
        binder.setBean(door);
    }

    public DoorEditor(UnitRepository unitRepository) {
        ComboBox<UnitComboBoxModel> unitField = new ComboBox<>("Устройство");
        unitField.setRequired(true);
        unitField.setPageSize(100);
        Map<String, UnitComboBoxModel> units = unitRepository.findAll()
                .stream()
                .map(unitMapper::toModel)
                .collect(Collectors.toMap(UnitComboBoxModel::clientId, unit -> unit));
        unitField.setItems(units.values());
        unitField.setItemLabelGenerator(UnitComboBoxModel::clientName);

        var save = new Button("Сохранить", VaadinIcon.CHECK.create());
        var cancel = new Button("Отмена");
        var delete = new Button("Удалить", VaadinIcon.TRASH.create());

        binder.forField(unitField)
                .withConverter(UnitComboBoxModel::clientId, units::get, "Invalid value")
                .bind("unitId");

        save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        save.addClickListener(e -> saveListener.onSave(currentDoor));
        save.addClickShortcut(Key.ENTER);

        delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
        delete.addClickListener(e -> deleteListener.onDelete(currentDoor));

        cancel.addClickListener(e -> cancelListener.onCancel());

        getContent().add(unitField, new HorizontalLayout(save, cancel, delete));
    }

}
