package com.example.computers.view;

import com.example.computers.entity.Computer;
import com.example.computers.entity.Location;
import com.example.computers.entity.Manufacturer;
import com.example.computers.repository.ComputerRepository;
import com.example.computers.repository.LocationRepository;
import com.example.computers.repository.ManufacturerRepository;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.IntegerField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import org.springframework.beans.factory.annotation.Autowired;

@Route(value = "computers", layout = MainView.class)
@PageTitle("Компьютеры")
public class ComputerView extends VerticalLayout {

    private final ComputerRepository computerRepository;
    private final ManufacturerRepository manufacturerRepository;
    private final LocationRepository locationRepository;
    private final Grid<Computer> grid = new Grid<>(Computer.class, false);

    @Autowired
    public ComputerView(ComputerRepository computerRepository,
                        ManufacturerRepository manufacturerRepository,
                        LocationRepository locationRepository) {
        this.computerRepository = computerRepository;
        this.manufacturerRepository = manufacturerRepository;
        this.locationRepository = locationRepository;

        grid.addColumn(Computer::getInventoryNumber).setHeader("Инв. номер");
        grid.addColumn(Computer::getModel).setHeader("Модель");
        grid.addColumn(Computer::getYear).setHeader("Год");
        grid.addColumn(Computer::getStatus).setHeader("Статус");
        grid.addColumn(c -> c.getManufacturer() != null ? c.getManufacturer().getName() : "").setHeader("Производитель");
        grid.addColumn(c -> c.getLocation() != null ? c.getLocation().toString() : "").setHeader("Локация");

        TextField searchField = new TextField();
        searchField.setPlaceholder("Поиск по модели, статусу...");
        searchField.setWidth("300px");
        searchField.addValueChangeListener(e -> {
            String val = e.getValue().trim();
            if (val.isEmpty()) updateList();
            else grid.setItems(computerRepository.search(val));
        });

        ComboBox<String> statusFilter = new ComboBox<>();
        statusFilter.setPlaceholder("Все статусы");
        statusFilter.setItems("В работе", "На ремонте", "Списан");
        statusFilter.setClearButtonVisible(true);
        statusFilter.setWidth("200px");
        statusFilter.addValueChangeListener(e -> {
            String val = e.getValue();
            if (val == null) updateList();
            else grid.setItems(computerRepository.findAll().stream()
                    .filter(c -> val.equals(c.getStatus()))
                    .toList());
        });

        HorizontalLayout filters = new HorizontalLayout(searchField, statusFilter);
        filters.setAlignItems(FlexComponent.Alignment.BASELINE);

        Button addButton    = new Button("Добавить",      ev -> openForm(new Computer()));
        Button editButton   = new Button("Редактировать", ev -> {
            Computer selected = grid.asSingleSelect().getValue();
            if (selected != null) openForm(selected);
        });
        Button deleteButton = new Button("Удалить", ev -> {
            Computer selected = grid.asSingleSelect().getValue();
            if (selected != null) { computerRepository.delete(selected); updateList(); }
        });

        add(new HorizontalLayout(addButton, editButton, deleteButton), filters, grid);
        updateList();
    }

    private void updateList() {
        grid.setItems(computerRepository.findAll());
    }

    private void openForm(Computer computer) {
        Dialog dialog = new Dialog();
        dialog.setWidth("500px");

        TextField inventoryNumber = new TextField("Инв. номер");
        inventoryNumber.setValue(computer.getInventoryNumber() != null ? computer.getInventoryNumber() : "");

        TextField model = new TextField("Модель");
        model.setValue(computer.getModel() != null ? computer.getModel() : "");

        IntegerField year = new IntegerField("Год");
        year.setValue(computer.getYear() != null ? computer.getYear() : 2023);

        TextField status = new TextField("Статус");
        status.setValue(computer.getStatus() != null ? computer.getStatus() : "В работе");

        ComboBox<Manufacturer> manufacturerBox = new ComboBox<>("Производитель");
        manufacturerBox.setItems(manufacturerRepository.findAll());
        manufacturerBox.setItemLabelGenerator(Manufacturer::getName);
        manufacturerBox.setValue(computer.getManufacturer());

        ComboBox<Location> locationBox = new ComboBox<>("Локация");
        locationBox.setItems(locationRepository.findAll());
        locationBox.setItemLabelGenerator(Location::toString);
        locationBox.setValue(computer.getLocation());

        Button save = new Button("Сохранить", e -> {
            computer.setInventoryNumber(inventoryNumber.getValue());
            computer.setModel(model.getValue());
            computer.setYear(year.getValue());
            computer.setStatus(status.getValue());
            computer.setManufacturer(manufacturerBox.getValue());
            computer.setLocation(locationBox.getValue());
            computerRepository.save(computer);
            dialog.close();
            updateList();
        });
        Button cancel = new Button("Отмена", e -> dialog.close());

        dialog.add(new VerticalLayout(
                new FormLayout(inventoryNumber, model, year, status, manufacturerBox, locationBox),
                new HorizontalLayout(save, cancel)));
        dialog.open();
    }
}