package ru.vyatsu.qr_access_admin.rent.component;

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.checkbox.Checkbox;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.datepicker.DatePicker;
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.component.textfield.TextField;
import com.vaadin.flow.component.timepicker.TimePicker;
import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.Binder;
import lombok.Getter;
import lombok.Setter;
import ru.vyatsu.qr_access_admin.client.entity.ClientEntity;
import ru.vyatsu.qr_access_admin.client.entity.ClientRepository;
import ru.vyatsu.qr_access_admin.door.entity.DoorEntity;
import ru.vyatsu.qr_access_admin.door.entity.DoorRepository;
import ru.vyatsu.qr_access_admin.rent.entity.RentEntity;

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

public class RentEditor extends Composite<VerticalLayout> {

    public interface SaveListener {
        void onSave(RentEntity rent);
    }

    public interface DeleteListener {
        void onDelete(RentEntity rent);
    }

    public interface CancelListener {
        void onCancel();
    }

    private volatile RentEntity currentRent;

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

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

    public void setCurrentRent(RentEntity rent) {
        this.currentRent = rent;
        binder.setBean(rent);
    }

    public RentEditor(DoorRepository doorRepository, ClientRepository clientRepository) {
        var startTimeField = new TimePicker("Время начала действия");
        var endTimeField = new TimePicker("Время окончания действия");
        var dateField = new DatePicker("Дата бронирования");
        var qrCodeField = new TextField("Закодированный идентификатор");
        var payedField = new Checkbox("Оплачено");
        ComboBox<DoorEntity> doorField = new ComboBox<>("Дверь");
        doorField.setItemLabelGenerator(DoorEntity::getDescription);
        ComboBox<ClientEntity> clientField = new ComboBox<>("Клиент");
        clientField.setItemLabelGenerator(ClientEntity::getEmail);
        Map<String, DoorEntity> doors = doorRepository.findAllByParentDoorIdsIsNull()
                .stream()
                .collect(Collectors.toMap(DoorEntity::getId, d -> d));
        Map<String, ClientEntity> clients = clientRepository.findAll()
                .stream()
                .collect(Collectors.toMap(ClientEntity::getId, c -> c));
        doorField.setItems(doors.values());
        clientField.setItems(clients.values());

        binder.forField(doorField)
                .withConverter(DoorEntity::getId, doors::get)
                .bind("doorId");
        binder.forField(clientField)
                .withConverter(ClientEntity::getId, clients::get)
                .bind("clientId");
        binder.forField(startTimeField).bind("startTime");
        binder.forField(endTimeField).bind("endTime");
        binder.forField(dateField).bind("date");
        binder.forField(qrCodeField).bind("qrCode");
        binder.forField(payedField).bind("payed");

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

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

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

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

        getContent().add(startTimeField, endTimeField, dateField, doorField, clientField, qrCodeField, payedField, new HorizontalLayout(save, cancel, delete));
    }
}
