import metadata from './block.json';
import { ValidatedTextInput, registerCheckoutBlock, extensionCartUpdate, getRegisteredBlock, ExperimentalOrderShippingPackages  } from '@woocommerce/blocks-checkout';
import { useSelect } from "@wordpress/data";
import { __ } from '@wordpress/i18n';

import {Fragment, useEffect, useRef, useState, useMemo, Component} from "react";
const { registerPlugin } = window.wp.plugins;


const getShippingRate = (cart) =>
{
	return cart.shipping_rates.find(x => x.rate_id.indexOf("pplcz_") > -1 && x.selected);
}

const getMetaData = (cart) => {
	return getShippingRate(cart)?.meta_data;
}

const getMetaValue = (cart, key) => {
	return getMetaData(cart)?.find(x => x.key === key)?.value;
}

const isMapAllowed = (cart) => !!parseInt(getMetaValue(cart, "mapEnabled"));

const isParcelRequired = (cart) => !!parseInt(getMetaValue(cart, "parcelRequired"));

const getHiddenPoints = (cart) => {

	const allowParcels = {
		ParcelBox: "parcelBoxEnabled" ,
		ParcelShop: "parcelShopEnabled" ,
		AlzaBox: "alzaBoxEnabled"
	}

	const meta = getMetaData(cart) || [];

	return Object.entries(allowParcels).filter(([key, metaKey]) => {
		return !meta.some((x) => x.key === metaKey && x.value);
	}).map(([key]) => key);

}



const getAllowedCountries = (cart) => getMetaValue(cart, "enabledParcelCountries") ?? [];


const parcelShopSelected = (cart) => {
	return cart.extensions?.["pplcz_parcelshop"]?.["parcelData"];
}

const parcelAddtionaldata = (cart) => {
	return cart.extensions?.["pplcz_parcelshop"]?.["additionalData"];
}

const ParcelShop = (props) => {

	const { cart, parcelRequired } = props;
	const parcelShop = parcelShopSelected(cart);
	return (
		<div>
			{parcelShop ?
				<>
					<strong>{__("Výdejní místo", "ppl-cz")}</strong><br/>
					<span>{parcelShop.name}</span>,&nbsp;
					<span>{parcelShop.street}</span>,&nbsp;
					<span>{parcelShop.zipCode}</span>,&nbsp;
					<span>{parcelShop.city}</span>
					<a href={"#"} onClick={e=>{e.preventDefault();PplMap(()=>{}, { lat: parcelShop?.gps.latitude, lng: parcelShop?.gps.longitude});}}>[{__("na mapě", "ppl-cz")}]</a>
				</> : (parcelRequired ? <>{__("Vyberte výdejní místo pro doručení zásilky", "ppl-cz")}</> : <>{__("Zboží bude dodáno na doručovací adresu", "ppl-cz")}</>)}
		</div>
	)
}

const restyle = (idsValues, cart, parcelShopBoxSelected)=> {

	const text = idsValues.map(x => {
		const finded = cart.shipping_rates.find(y => y.rate_id === x);

		if (!finded?.rate_id.startsWith("pplcz_")) {
			return "";
		}
		const classNameSet = {
			"background-size": "auto 1em",
			"background-position": "center center",
			"background-repeat": "no-repeat",
			"display": "inline-block",
			"content": "''",
			"height": "1em",
			"vertical-align": "middle"
		}

		let image = `${parcelshop_block_frontend.assets_url}/small_logo.png`;

		if (finded.meta_data.some(x => x.key === "parcelRequired" && x.value == 1 || x.key ==="mapEnabled" && x.value == 1)) {
			image = `${parcelshop_block_frontend.assets_url}/small_logo.png`
			if (finded.selected) {
				if (parcelShopBoxSelected?.accessPointType === "ParcelShop") {
					image = `${parcelshop_block_frontend.assets_url}/small_logo.png`
				} else if (parcelShopBoxSelected?.accessPointType === "ParcelBox") {
					image = `${parcelshop_block_frontend.assets_url}/small_logo.png`
				}
			}
		}

		classNameSet["background-image"] = `url('${image}')`;


		classNameSet["width"] = "2em";

		const className =  cart.shipping_rates.length !== 1 ? `.wc-block-components-shipping-rates-control #radio-control-0-${x.replace(":", "\\:")}__label::after`: `.wc-block-components-shipping-rates-control  .wc-block-components-radio-control__label:before`;
		if (cart.shipping_rates.length === 1)
		{
			classNameSet.display = "block";
		}
		const classAll = `${className} {
				${Object.keys(classNameSet).map(x => `${x}: ${classNameSet[x]};`).join("\n")}  
			}`;
		return classAll;
	}).join("\n");

	const style = document.getElementById("ppl-shipping-images") || document.createElement("style");

	if (!style.id) {
		style.id = "ppl-shipping-images";
		document.head.appendChild(style);
	}

	style.innerHTML = text;
}

const PosnContent = ({ cart, parcelShopSelected}) => {

	const savingData = (posn) => {
		extensionCartUpdate({
			namespace: 'pplcz_parcelshop',
			data: {
				"additionalData": {
					'posn': posn
				}
			}
		});
	}
	const additinalData = parcelAddtionaldata(cart);

	const [value, setValue] = useState(additinalData?.posn || '');

	useEffect(() => {
		if ((value  || '') !== (additinalData?.posn || '')) {
			const timeout = setTimeout(() => {
				savingData(value)
			}, 500);
			return () => clearTimeout(timeout);
		}
	}, [value]);

	if (parcelShopSelected && parcelShopSelected.country === 'DE' &&
		(parcelShopSelected.accessPointType !== 'ParcelShop'))
	{
		return <div id="pplcz_posn_item" className="wc-block-components-text-input wc-block-components-address-form__first_name is-active">
			<input type="text" id="pplcz_posn"  onChange={e=>{
				setValue(e.target.value);
			}} aria-label="POSN" aria-describedby="" required="true" aria-invalid="false" title="" value={value}/>
				<label htmlFor="pplcz_posn">{__('Postident ID *')}</label>
			</div>
	}
	return null;
}

// Vnitřní komponenta - zde už máme jistotu, že cart a payment existují
const BlockContent = ({ cart, payment, parcelShopBoxSelected }) => {

	const firstShippingMethod = cart.shippingRates[0];
	const rateId = firstShippingMethod?.shipping_rates.find(x => x.selected === true && x.method_id.indexOf("pplcz_") > -1);
	const shippingAddress = firstShippingMethod?.destination;
	const onUpdateComponent = useRef(false);

	const { parcelRequired, mapAllowed, hiddenPoints, allowedCountries, mapSetting} = useMemo(() => {

		const parcelRequired = isParcelRequired(firstShippingMethod);
		const mapAllowed = isMapAllowed(firstShippingMethod);

		const hiddenPoints = getHiddenPoints(firstShippingMethod);
		const allowedCountries = getAllowedCountries(firstShippingMethod);

		let address = '';
		let country = '';

		if(shippingAddress){
			address = [
				[shippingAddress.address_1, shippingAddress.address_2].filter(x=>x).join(' '),
				[shippingAddress.postcode, shippingAddress.city].filter(x=>x).join(' ')
			].filter(x => x).join(', ');
			country = shippingAddress.country?.toLowerCase() || '';
		}
		if (parcelShopBoxSelected) {
			address = [
				parcelShopBoxSelected.street,
				[parcelShopBoxSelected.zipCode, parcelShopBoxSelected.city].filter(x => x).join(' ')
			].filter(x => x).join(', ');
			country = parcelShopBoxSelected.country || '';
		}
		const mapSetting = {
			address,
			country,
			hiddenPoints: hiddenPoints.length ? hiddenPoints.join(',') : null,
			countries: allowedCountries.map(c => c.toLowerCase()).join(',')
		};

		return { parcelRequired, mapAllowed, hiddenPoints, allowedCountries, mapSetting };
	}, [rateId]);

	window.pplczLastPplMapData = mapSetting;

	const isCart = Array.from(document.getElementsByTagName("meta")).some(x => {
		return x.property === 'pplcz:cart' && x.content === "1";
	});

	const hideComponent = !parcelRequired || !mapAllowed || isCart;

	const savingData = (parcelShop) => {
		extensionCartUpdate({
			namespace: 'pplcz_parcelshop',
			data: {
				"parcelData": parcelShop
			}
		});
	}

	useEffect(() => {
		if (!onUpdateComponent.current) {
			onUpdateComponent.current = true;
			return;
		}
		if (parcelRequired && !parcelShopBoxSelected && !hideComponent) {
			PplMap(savingData, {...mapSetting});
		}
	}, [parcelRequired, parcelShopBoxSelected]);

	if (hideComponent)
		return null;

	let messages = [];

	if (parcelRequired && !parcelShopBoxSelected)
		messages.push(<li key={"ageControl"}>{__("Pro dodání zboží je nutno vybrat jedno z výdejních míst", "ppl-cz")}</li>);

	return (
		<div>
			<ParcelShop cart={cart} parcelRequired={parcelRequired}/>
			<a href="#withCard" className={"pplcz-select-parcelshop"} onClick={e => {
				e.preventDefault();
				PplMap(savingData, {...mapSetting});
			}}>{__("Výběr výdejního místa", "ppl-cz")}</a>

			{parcelShopBoxSelected && (
				<> / <a href={"#"} className={"pplcz-clear-map"} onClick={e => {
					e.preventDefault();
					onUpdateComponent.current = false;
					savingData(null);
				}}>{__("Zrušit výběr", "ppl-cz")}</a></>
			)}
			<br/>
			<PosnContent cart={cart} parcelShopSelected={parcelShopBoxSelected}/>
			{messages.length > 0 && <ul>{messages}</ul>}
		</div>
	);
}

// Wrapper komponenta - načte data a předá je dál
const Block = (props) => {

	const { cart, payment } = useSelect((select) => ({
		cart: select("wc/store/cart").getCartData(),
		payment: select("wc/store/payment").getActivePaymentMethod()
	}));

	// Bezpečně získáme hodnoty pro restyle
	const firstShippingMethod = cart?.shippingRates?.[0];
	const parcelShopBoxSelected = cart ? parcelShopSelected(cart) : null;

	const idsValues = useMemo(() => {
		if (!cart?.shippingRates?.length) return [];
		return [...new Set(cart.shippingRates.reduce((acc, x) => {
			return acc.concat(x.shipping_rates?.map(y => y.rate_id) || []);
		}, []))].sort();
	}, [cart?.shippingRates]);

	// Restyle se volá vždy, když máme potřebná data

	useEffect(() => {
		if (firstShippingMethod?.shipping_rates?.length) {
			restyle(idsValues, firstShippingMethod, parcelShopBoxSelected);
		}
	}, [idsValues, firstShippingMethod, parcelShopBoxSelected?.accessPointType]);


	// Guard - pokud nemáme data, nevykreslíme BlockContent
	if (!cart || !payment || !cart.shippingRates?.length) {
		return null;
	}

	return <BlockContent cart={cart} payment={payment} parcelShopBoxSelected={parcelShopBoxSelected} />;
}

const options = {
	metadata,
	component: Block
};

registerCheckoutBlock(options);