package com.ecep.contract.controller.project;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import com.ecep.contract.controller.project.satisfaction_survey.CustomerSatisfactionSurveyWindowController;
import com.ecep.contract.controller.tab.RefreshableSkin;
import com.ecep.contract.controller.table.cell.EmployeeTableCell;
import com.ecep.contract.converter.CompanyStringConverter;
import com.ecep.contract.converter.EmployeeStringConverter;
import com.ecep.contract.model.CustomerSatisfactionSurvey;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.Project;
import com.ecep.contract.service.CompanyCustomerFileService;
import com.ecep.contract.service.CompanyCustomerService;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.CustomerSatisfactionSurveyService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.vm.CustomerSatisfactionSurveyViewModel;

import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import javafx.util.converter.LocalDateStringConverter;
import lombok.Setter;

@FxmlPath("/ui/project/project-tab-customer-satisfaction-survey.fxml")
public class ProjectTabSkinCustomerSatisfactionSurvey
        extends AbstProjectTableTabSkin<CustomerSatisfactionSurvey, CustomerSatisfactionSurveyViewModel>
        implements RefreshableSkin {

    public TableColumn<CustomerSatisfactionSurveyViewModel, Number> idColumn;
    public TableColumn<CustomerSatisfactionSurveyViewModel, String> codeColumn;
    public TableColumn<CustomerSatisfactionSurveyViewModel, Number> totalScoreColumn;
    public TableColumn<CustomerSatisfactionSurveyViewModel, Employee> applicantColumn;
    public TableColumn<CustomerSatisfactionSurveyViewModel, LocalDateTime> applyTimeColumn;
    public TableColumn<CustomerSatisfactionSurveyViewModel, String> descriptionColumn;
    public TableColumn<CustomerSatisfactionSurveyViewModel, LocalDate> dateColumn;

    @Setter
    private CustomerSatisfactionSurveyService satisfactionSurveyService;
    @Setter
    private LocalDateStringConverter localDateStringConverter;
    @Setter
    private EmployeeStringConverter employeeStringConverter;
    @Setter
    private CompanyStringConverter companyStringConverter;
    @Setter
    private CompanyService companyService;
    @Setter
    private CompanyCustomerService customerService;
    @Setter
    private CompanyCustomerFileService customerFileService;

    public ProjectTabSkinCustomerSatisfactionSurvey(ProjectWindowController controller) {
        super(controller);
    }

    @Override
    protected CustomerSatisfactionSurveyService getViewModelService() {
        return getCustomerSatisfactionSurveyService();
    }

    @Override
    public Tab getTab() {
        return controller.satisfactionTab;
    }

    @Override
    public void initializeTable() {
        super.initializeTable();

        bindNumberColumn(idColumn, CustomerSatisfactionSurveyViewModel::getId);
        bindColumn(codeColumn, CustomerSatisfactionSurveyViewModel::getCode);
        bindLocalDateColumn(dateColumn, CustomerSatisfactionSurveyViewModel::getDate);
        bindNumberColumn(totalScoreColumn, CustomerSatisfactionSurveyViewModel::getTotalScore);
        applicantColumn.setCellValueFactory(param -> param.getValue().getApplicant());
        applicantColumn.setCellFactory(cell -> new EmployeeTableCell<>(getEmployeeService()));
        bindLocalDateTimeColumn(applyTimeColumn, CustomerSatisfactionSurveyViewModel::getApplyTime);
        bindColumn(descriptionColumn, CustomerSatisfactionSurveyViewModel::getDescription);
    }

    @Override
    protected CustomerSatisfactionSurveyViewModel createNewViewModel() {
        CustomerSatisfactionSurveyViewModel model = super.createNewViewModel();
        Project project = getParent();
        model.getApplicant().set(controller.getCurrentUser());
        LocalDate created = project.getCreated();
        if (created == null) {
            created = LocalDate.now();
        }
        model.getApplyTime().set(LocalDateTime.of(created, LocalTime.now()));
        saveRow(model);

        showInOwner(CustomerSatisfactionSurveyWindowController.class, model);

        return model;
    }

    @Override
    protected void onTableRowDoubleClickedAction(CustomerSatisfactionSurveyViewModel item) {
        showInOwner(CustomerSatisfactionSurveyWindowController.class, item);
    }

    private CustomerSatisfactionSurveyService getCustomerSatisfactionSurveyService() {
        if (satisfactionSurveyService == null) {
            satisfactionSurveyService = getBean(CustomerSatisfactionSurveyService.class);
        }
        return satisfactionSurveyService;
    }

    private LocalDateStringConverter getLocalDateStringConverter() {
        if (localDateStringConverter == null) {
            localDateStringConverter = new LocalDateStringConverter(DateTimeFormatter.ISO_LOCAL_DATE, null);
        }
        return localDateStringConverter;
    }

    private EmployeeStringConverter getEmployeeStringConverter() {
        if (employeeStringConverter == null) {
            employeeStringConverter = getBean(EmployeeStringConverter.class);
        }
        return employeeStringConverter;
    }

    public CompanyService getCompanyService() {
        if (companyService == null) {
            companyService = getBean(CompanyService.class);
        }
        return companyService;
    }

    private CompanyStringConverter getCompanyStringConverter() {
        if (companyStringConverter == null) {
            companyStringConverter = getBean(CompanyStringConverter.class);
        }
        return companyStringConverter;
    }

    private CompanyCustomerService getCompanyCustomerService() {
        if (customerService == null) {
            customerService = getBean(CompanyCustomerService.class);
        }
        return customerService;
    }

    private CompanyCustomerFileService getCompanyCustomerFileService() {
        if (customerFileService == null) {
            customerFileService = getBean(CompanyCustomerFileService.class);
        }
        return customerFileService;
    }

}
