package cn.net.connor.std.processedit.meopviewfx.bean;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import com.teamcenter.rac.aifrcp.AIFUtility;
import com.teamcenter.rac.kernel.SoaUtil;
import com.teamcenter.rac.kernel.TCComponent;
import com.teamcenter.rac.kernel.TCComponentBOMLine;
import com.teamcenter.rac.kernel.TCComponentItem;
import com.teamcenter.rac.kernel.TCComponentItemRevision;
import com.teamcenter.rac.kernel.TCComponentItemType;
import com.teamcenter.rac.kernel.TCSession;
import com.teamcenter.services.internal.rac.structuremanagement.StructureService;
import com.teamcenter.services.internal.rac.structuremanagement._2011_06.Structure;

import cn.net.connor.std.aifrcp.util.KUtil;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.layout.Region;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;

public class KTableRow {

	public static final String BOMLINE = "BOMLINE";
	public static final String ITEM = "ITEM";
	public static final String ITEMMASTER = "ITEMMASTER";
	public static final String REV = "REV";
	public static final String REVMASTER = "REVMASTER";
	private static double ZOOM = 1;
	static {
		try {
			ZOOM = ((TCSession) AIFUtility.getCurrentApplication().getSession()).getPreferenceService().getDoubleValue("Connor_AVIC_GXBZ_Web_Zoom");
		} catch (Exception e) {
		}
		if (ZOOM < 0) {
			ZOOM = 1;
		}
		System.out.println("GDT ZOOM = " + ZOOM);
	}

	private TCComponentBOMLine bomline;
	private TCComponentItem item;
	private TCComponentItemRevision rev;
	private TCComponent itemMaster;
	private TCComponent revMaster;
	private boolean showWebView = true;
	private WebView webView;
	private String webContent;

	public KTableRow(TCComponentBOMLine bomline, TCComponentItem item, TCComponentItemRevision rev, TCComponent itemMaster, TCComponent revMaster) {
		this.bomline = bomline;
		this.item = item;
		this.rev = rev;
		this.itemMaster = itemMaster;
		this.revMaster = revMaster;
	}

	public Map<PropConfig, SimpleStringProperty> stringProps = new HashMap<PropConfig, SimpleStringProperty>();
	protected Map<PropConfig, String> savedValues = new HashMap<PropConfig, String>();

	public TCComponentBOMLine getBomLine() {
		return this.bomline;
	}

	public void setValueByPropName(String config, String value) throws Exception {
		if (KUtil.isEmpty(config)) {
			return;
		}
		System.out.println("Set Row Value [" + config + "] = [" + value + "]");
		for (PropConfig propConfig : stringProps.keySet()) {
			if (config.equalsIgnoreCase(propConfig.propName)) {
				stringProps.get(propConfig).setValue(value);
			}
		}
		System.out.println(">> config not found");
	}

	public boolean parseConfig(PropConfig config) throws Exception {
		if (config == null) {
			return true;
		}
		String value = getTCValue(config.propLoc, config.propName);
		stringProps.put(config, new SimpleStringProperty(value));
		savedValues.put(config, value);
		if (!KUtil.isEmpty(config.filterValue)) {
			// && !config.filterValue.equals(value)
			// 20200722 split filter
			String[] filters = config.filterValue.split(";");
			boolean checkOK = false;
			for (String string : filters) {
				if (string.equals(value)) {
					checkOK = true;
					break;
				}
			}
			return checkOK;
		}
		return true;
	}

	public String getTCValue(String proploc, String propName) throws Exception {
		TCComponent comp = getTCComponent(proploc);
		if (comp == null) {
			return "";
		}
		return comp.getStringProperty(propName);
	}

	public TCComponent getTCComponent(String proploc) {
		if (KUtil.isEmpty(proploc)) {
			return bomline;
		}
		proploc = proploc.toUpperCase();
		switch (proploc) {
		case BOMLINE:
			return bomline;
		case ITEM:
			return item;
		case REV:
			return rev;
		case ITEMMASTER:
			return itemMaster;
		case REVMASTER:
			return revMaster;
		default:
			System.out.println(">> Prop location error: " + proploc);
			break;
		}
		return null;
	}

	private boolean loadTCValues(Map<String, String> bomlinePropMap, Map<String, String> itemPropMap, Map<String, String> revPropMap, Map<String, String> itemMasterPropMap,
			Map<String, String> revMasterPropMap) {
		boolean modified = false;
		for (PropConfig config : stringProps.keySet()) {
			if (!config.canEdit) {
				continue;
			}
			String value = stringProps.get(config).getValueSafe();
			if (savedValues.containsKey(config)) {
				String savedValue = savedValues.get(config);
				if (value.equals(savedValue)) {
					continue;
				}
			}
			modified = true;
			String propName = config.propName;
			String proploc = config.propLoc.toUpperCase();
			System.out.println(">> " + proploc + "." + propName + " = " + value);
			switch (proploc) {
			case BOMLINE:
				bomlinePropMap.put(propName, value);
				break;
			case ITEM:
				itemPropMap.put(propName, value);
				if ("object_name".equals(propName)) {
					revPropMap.put(propName, value);
				}
				break;
			case REV:
				revPropMap.put(propName, value);
				if ("object_name".equals(propName)) {
					itemPropMap.put(propName, value);
				}
				break;
			case ITEMMASTER:
				itemMasterPropMap.put(propName, value);
				break;
			case REVMASTER:
				revMasterPropMap.put(propName, value);
				break;
			default:
				System.out.println(">> Prop location error: " + proploc);
				break;
			}
		}
		return modified;
	}

	public void saveTCData(TCComponentBOMLine parentLine, TCComponentItemType itemType, int precise, TCComponent viewTypeTag) throws Exception {
		if (bomline == null) {
			if (itemType != null && parentLine != null) {
				System.out.println("Create New Row...");
				item = itemType.create(itemType.getNewID(), itemType.getNewRev(null), itemType.getName(), "-", "", null);
				System.out.println(">> new item: " + item);
				rev = item.getLatestItemRevision();
				itemMaster = item.getRelatedComponent("IMAN_master_form");
				revMaster = rev.getRelatedComponent("IMAN_master_form_rev");
				bomline = parentLine.add(item, rev, null, false, "");
			}
		}
		if (bomline == null) {
			return;
		}
		System.out.println("Update: " + bomline + ", Precise = " + precise);
		if (precise != 0) {
			TCComponent[] bvrs = rev.getReferenceListProperty("structure_revisions");
			System.out.println("BVR: " + Arrays.toString(bvrs));
			if (KUtil.getLen(bvrs) == 0) {
				TCSession session = rev.getSession();
				StructureService structureService = StructureService.getService(session);
				Structure.CreateOrSaveAsPSBOMViewRevisionResponse createOrSaveAsPSBOMViewRevisionResponse = null;
				Structure.CreateOrSaveAsPSBOMViewRevisionInput[] arrayOfCreateOrSaveAsPSBOMViewRevisionInput = new Structure.CreateOrSaveAsPSBOMViewRevisionInput[1];
				arrayOfCreateOrSaveAsPSBOMViewRevisionInput[0] = new Structure.CreateOrSaveAsPSBOMViewRevisionInput();
				(arrayOfCreateOrSaveAsPSBOMViewRevisionInput[0]).clientId = (new Integer(0)).toString();
				(arrayOfCreateOrSaveAsPSBOMViewRevisionInput[0]).isPrecise = precise > 0;
				(arrayOfCreateOrSaveAsPSBOMViewRevisionInput[0]).viewTypeTag = viewTypeTag;
				(arrayOfCreateOrSaveAsPSBOMViewRevisionInput[0]).itemObject = rev.getItem();
				(arrayOfCreateOrSaveAsPSBOMViewRevisionInput[0]).itemRevObj = rev;
				createOrSaveAsPSBOMViewRevisionResponse = structureService.createOrSavePSBOMViewRevision(arrayOfCreateOrSaveAsPSBOMViewRevisionInput);
				SoaUtil.checkPartialErrors(createOrSaveAsPSBOMViewRevisionResponse.serviceData);
			} else {
				bomline.setPrecision(precise > 0);
			}
		}
		Map<String, String> revPropMap = new HashMap<>();
		Map<String, String> revMasterPropMap = new HashMap<>();
		Map<String, String> itemPropMap = new HashMap<>();
		Map<String, String> itemMasterPropMap = new HashMap<>();
		Map<String, String> bomlinePropMap = new HashMap<>();
		if (!loadTCValues(bomlinePropMap, itemPropMap, revPropMap, itemMasterPropMap, revMasterPropMap)) {
			return;
		}
		if (itemPropMap.size() > 0) {
			item.setProperties(itemPropMap);
		}
		if (revPropMap.size() > 0) {
			rev.setProperties(revPropMap);
		}
		if (itemMasterPropMap.size() > 0) {
			itemMaster.setProperties(itemMasterPropMap);
		}
		if (revMasterPropMap.size() > 0) {
			revMaster.setProperties(revMasterPropMap);
		}
		if (bomlinePropMap.size() > 0) {
			bomline.setProperties(bomlinePropMap);
		}
		bomline.refresh();
	}

	public void removeLine() throws Exception {
		if (bomline != null) {
			System.out.println(">> Remove: " + bomline);
			bomline.cut();
		}
	}

	public void showWebView(boolean showWebView) {
		this.showWebView = showWebView;
	}

	public boolean showWebView() {
		return showWebView;
	}

	public WebView getWebView() {
		return this.webView;
	}

	public WebView checkWebView() {
		if (!showWebView) {
			return null;
		}
		if (webView == null) {
			webView = new WebView();
			webView.setDisable(true);
			webView.setMouseTransparent(true);
			webView.setPrefHeight(Region.USE_COMPUTED_SIZE);
			webView.setZoom(ZOOM);
			// webView.getEngine().documentProperty().addListener((obj, prev, newv) -> {
			// if (newv == null) {
			// return;
			// }
			// try {
			// // String heightText = webView.getEngine().executeScript(
			// // "var body = document.body, html = document.documentElement;Math.max(
			// // body.scrollHeight, body.offsetHeight, html.clientHeight,
			// html.scrollHeight,
			// // html.offsetHeight );")
			// // .toString();
			//
			// // double height = Double.parseDouble(heightText.replace("px", ""));
			// // webView.setPrefHeight(height + 12);
			// // System.out.println("Set Height [" + getTCComponent(BOMLINE) + "]: " +
			// // height);
			// new Thread(() -> {
			// Platform.runLater(() -> {
			// String heightText = webView.getEngine().executeScript("var body =
			// document.body, html = document.documentElement;Math.max( body.scrollHeight,
			// body.offsetHeight );")
			// .toString();
			// double height2 = Double.parseDouble(heightText.replace("px", "")) + 12;
			// System.out.println("Set Height [" + getTCComponent(BOMLINE) + "][" +
			// webView.getWidth() + "]: " + height2);
			// webView.setPrefHeight(height2);
			// webView.getParent().layout();
			// webView.layout();
			// });
			// }).start();
			// } catch (Exception e) {
			// e.printStackTrace();
			// }
			// });
			// webView.getEngine().getLoadWorker().stateProperty().addListener(new
			// ChangeListener<State>() {
			// @Override
			// public void changed(ObservableValue<? extends State> observable, State
			// oldValue, State newValue) {
			// if (newValue == State.SUCCEEDED) {
			// // webView.setPrefHeight(Region.USE_COMPUTED_SIZE);
			// }
			// }
			// });
		}
		return webView;
	}

	public void loadContent(String html) {
		if (html == null) {
			html = "";
		}
		if (html.equals(this.webContent)) {
			return;
		}
		webView.setPrefWidth(Region.USE_COMPUTED_SIZE);
		webView.setPrefHeight(Region.USE_COMPUTED_SIZE);
		WebEngine engine = webView.getEngine();
		this.webContent = html;
		engine.loadContent(html);
	}
}
