package com.ecep.contract.controller.vendor.purchase.order;

import java.time.LocalDateTime;
import java.util.Map;

import com.ecep.contract.SpringApp;
import com.ecep.contract.controller.tab.TabSkin;
import com.ecep.contract.controller.table.AbstEntityTableTabSkin;
import com.ecep.contract.controller.table.cell.LocalDateTimeTableCell;
import com.ecep.contract.controller.vendor.PurchaseBillVoucherWindowController;
import com.ecep.contract.controller.vendor.PurchaseOrderWindowController;
import com.ecep.contract.converter.EmployeeStringConverter;
import com.ecep.contract.converter.EntityStringConverter;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.Invoice;
import com.ecep.contract.model.PurchaseBillVoucher;
import com.ecep.contract.model.PurchaseOrder;
import com.ecep.contract.service.InvoiceService;
import com.ecep.contract.service.PurchaseBillVoucherService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.vm.PurchaseBillVoucherViewModel;
import com.ecep.contract.vm.PurchaseOrderViewModel;

import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.StringConverter;
import lombok.Setter;

@FxmlPath("/ui/contract/purchase-orders-tab-bill-voucher.fxml")
public class PurchaseOrderTabSkinBillVoucher
        extends
        AbstEntityTableTabSkin<PurchaseOrderWindowController, PurchaseOrder, PurchaseOrderViewModel, PurchaseBillVoucher, PurchaseBillVoucherViewModel>
        implements TabSkin {

    @Setter
    PurchaseBillVoucherService billVoucherService;
    @Setter
    private EmployeeStringConverter employeeStringConverter;
    @Setter
    private InvoiceService invoiceService;

    /* 以下是合同内容 */
    public TableColumn<PurchaseBillVoucherViewModel, Number> idColumn;
    public TableColumn<PurchaseBillVoucherViewModel, String> refIdColumn;
    public TableColumn<PurchaseBillVoucherViewModel, String> codeColumn;
    public TableColumn<PurchaseBillVoucherViewModel, Invoice> invoiceColumn;
    public TableColumn<PurchaseBillVoucherViewModel, Employee> employeeColumn;
    public TableColumn<PurchaseBillVoucherViewModel, Employee> makerColumn;
    public TableColumn<PurchaseBillVoucherViewModel, Employee> verifierColumn;

    public TableColumn<PurchaseBillVoucherViewModel, LocalDateTime> makerDateColumn;
    public TableColumn<PurchaseBillVoucherViewModel, LocalDateTime> verifierDateColumn;
    public TableColumn<PurchaseBillVoucherViewModel, LocalDateTime> modifyDateColumn;
    public TableColumn<PurchaseBillVoucherViewModel, String> descriptionColumn;

    public PurchaseOrderTabSkinBillVoucher(PurchaseOrderWindowController controller) {
        super(controller);
    }

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

    @Override
    protected PurchaseBillVoucherService getViewModelService() {
        return getPurchaseBillVoucherService();
    }

    // @Override
    // protected List<PurchaseBillVoucherViewModel> loadTableData(PurchaseOrder
    // order) {
    // List<PurchaseBillVoucher> list =
    // getPurchaseBillVoucherService().findAll((root, q, cb) -> {
    // // 创建子查询：获取 voucher_id 列表
    // Subquery<Long> subquery = q.subquery(Long.class);
    // Root<PurchaseBillVoucherItem> vi =
    // subquery.from(PurchaseBillVoucherItem.class);
    // Join<PurchaseBillVoucherItem, PurchaseOrderItem> oi = vi.join("orderItem",
    // JoinType.LEFT);
    //
    // subquery.select(vi.get("voucher").get("id"))
    // .where(cb.equal(oi.get("order"), order))
    // .distinct(true);
    //
    // // 主查询：筛选出 voucher.id 在子查询结果中的记录
    // return cb.in(root.get("id")).value(subquery);
    //
    //// Subquery<PurchaseBillVoucher> subquery =
    // q.subquery(PurchaseBillVoucher.class);
    //// Root<PurchaseBillVoucherItem> vi =
    // subquery.from(PurchaseBillVoucherItem.class);
    //// Join<PurchaseBillVoucherItem, PurchaseOrderItem> oi = vi.join("orderItem",
    // JoinType.LEFT);
    ////
    //// subquery.select(vi.get("voucher"))
    //// .where(cb.equal(oi.get("order"), order))
    //// .distinct(true);
    ////
    //// // 主查询：筛选 root 在子查询结果中的记录
    //// return cb.equal(root, subquery.getSelection());
    // }, getSortByTable());
    //
    // return list.stream().map(PurchaseBillVoucherViewModel::from).toList();
    // }

    // @Override
    // public Specification<PurchaseBillVoucher> getSpecification(PurchaseOrder
    // parent) {
    // return SpecificationUtils.and(getSpecification(), (root, query, builder) -> {
    // // 创建子查询：获取 voucher_id 列表
    // Subquery<Long> subquery = query.subquery(Long.class);
    // Root<PurchaseBillVoucherItem> vi =
    // subquery.from(PurchaseBillVoucherItem.class);
    // Join<PurchaseBillVoucherItem, PurchaseOrderItem> oi = vi.join("orderItem",
    // JoinType.LEFT);

    // subquery.select(vi.get("voucher").get("id"))
    // .where(builder.equal(oi.get("order"), parent))
    // .distinct(true);

    // // 主查询：筛选出 voucher.id 在子查询结果中的记录
    // return builder.in(root.get("id")).value(subquery);
    // });
    // }

    public Map<String, Object> getSpecification(PurchaseOrder parent) {
        Map<String, Object> params = getSpecification();
        params.put("purchaseOrder", parent);
        return params;
    }

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

        idColumn.setCellValueFactory(param -> param.getValue().getId());
        codeColumn.setCellValueFactory(param -> param.getValue().getCode());
        refIdColumn.setCellValueFactory(param -> param.getValue().getRefId().asString());
        employeeColumn.setCellValueFactory(param -> param.getValue().getEmployee());

        invoiceColumn.setCellValueFactory(param -> param.getValue().getInvoice());
        invoiceColumn.setCellFactory(TextFieldTableCell.forTableColumn(getInvoiceStringConverter()));

        employeeColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
        makerColumn.setCellValueFactory(param -> param.getValue().getMaker());
        makerColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
        verifierColumn.setCellValueFactory(param -> param.getValue().getVerifier());
        verifierColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));

        makerDateColumn.setCellValueFactory(param -> param.getValue().getMakerDate());
        makerDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
        verifierDateColumn.setCellValueFactory(param -> param.getValue().getVerifierDate());
        verifierDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
        modifyDateColumn.setCellValueFactory(param -> param.getValue().getModifyDate());
        modifyDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());

        descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription());
    }

    private StringConverter<Invoice> getInvoiceStringConverter() {
        EntityStringConverter<Invoice> stringConverter = new EntityStringConverter<>();
        stringConverter.setInitialized(cc -> getInvoiceService().findById(cc.getId()));
        stringConverter.setFormater(Invoice::toPrettyString);
        return stringConverter;
    }

    @Override
    protected void createContextMenu(ContextMenu contextMenu) {
        MenuItem item2 = new MenuItem("刷新");
        item2.setOnAction(this::onTableRefreshAction);

        MenuItem item3 = new MenuItem("删除");
        item3.setOnAction(this::onTableDeleteAction);

        contextMenu.getItems().addAll(item2, item3);
    }

    @Override
    protected void onTableRowDoubleClickedAction(PurchaseBillVoucherViewModel item) {
        showInOwner(PurchaseBillVoucherWindowController.class, item);
    }

    PurchaseBillVoucherService getPurchaseBillVoucherService() {
        if (billVoucherService == null) {
            billVoucherService = SpringApp.getBean(PurchaseBillVoucherService.class);
        }
        return billVoucherService;
    }

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

    public InvoiceService getInvoiceService() {
        if (invoiceService == null) {
            invoiceService = SpringApp.getBean(InvoiceService.class);
        }
        return invoiceService;
    }
}
