/**
 * Uniwersalny injector pola NIP w koszyku / checkout.
 *
 * Działa dla:
 *   - natywny WooCommerce checkout (classic) — pola dodawane przez PHP, ten skrypt tylko wymusza widoczność
 *   - WooCommerce Blocks (Cart/Checkout block) — wkleja pola pod email
 *   - CartFlows / FunnelKit / WooFunnels / inne external checkouts
 *
 * Detection: jakikolwiek element [name=billing_email] LUB [name=email] na stronie.
 * Idempotentne — sprawdza czy pole już istnieje, nie duplikuje.
 *
 * Wartość trafia jako hidden input "billing_ksef_nip" + "billing_ksef_request_invoice" do
 * $_POST → Checkout_Field::save_to_order() już to czyta.
 */
(function(){
	'use strict';

	if (window.__ksefNipInjected) return;
	window.__ksefNipInjected = true;

	const CFG = window.KSEF_CHECKOUT_INJECT || {
		label_checkbox: 'Chcę otrzymać fakturę VAT',
		label_type: 'Rodzaj faktury',
		label_type_company: 'Na firmę (z NIP)',
		label_type_person: 'Na osobę fizyczną (bez NIP)',
		label_nip: 'Wpisz numer NIP',
		label_person_other: 'Faktura na inne dane niż dane zamówienia',
		label_person_name: 'Imię i nazwisko',
		label_person_street: 'Ulica i numer',
		label_person_zip: 'Kod pocztowy',
		label_person_city: 'Miejscowość',
		placeholder: '10 cyfr, bez kresek',
	};

	function buildField() {
		const wrapper = document.createElement('div');
		wrapper.className = 'ksef-nip-field';
		wrapper.style.cssText = 'margin:14px 0;padding:12px;border:1px solid #e3e5e8;border-radius:6px;background:#fafbfc;';
		wrapper.innerHTML = `
			<label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:14px;">
				<input type="checkbox" id="ksef-request-invoice" name="billing_ksef_request_invoice" value="1">
				<span>${CFG.label_checkbox}</span>
			</label>
			<div id="ksef-invtype-wrapper" style="display:none;margin-top:10px;">
				<label style="display:block;font-size:13px;margin-bottom:4px;color:#555;">${CFG.label_type || 'Rodzaj faktury'}</label>
				<select id="ksef-invtype" name="billing_ksef_invoice_type"
					style="width:100%;max-width:300px;padding:8px 10px;border:1px solid #c3c4c7;border-radius:4px;font-size:14px;">
					<option value="company">${CFG.label_type_company || 'Na firmę (z NIP)'}</option>
					<option value="person">${CFG.label_type_person || 'Na osobę fizyczną (bez NIP)'}</option>
				</select>
			</div>
			<div id="ksef-nip-wrapper" style="display:none;margin-top:10px;">
				<label style="display:block;font-size:13px;margin-bottom:4px;color:#555;">${CFG.label_nip}</label>
				<input type="text" id="ksef-nip-input" name="billing_ksef_nip" placeholder="${CFG.placeholder}" maxlength="10" pattern="\\d{10}" inputmode="numeric"
					style="width:100%;max-width:300px;padding:8px 10px;border:1px solid #c3c4c7;border-radius:4px;font-size:14px;">
				<small style="display:block;color:#888;margin-top:4px;font-size:11px;">Faktura trafi do Krajowego Systemu e-Faktur (KSeF)</small>
				<div id="ksef-gus-result" style="display:none;margin-top:8px;font-size:13px;line-height:1.45;padding:8px 10px;border-radius:4px;"></div>
			</div>
			<div id="ksef-person-fields" style="display:none;margin-top:10px;">
				<label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;"><input type="checkbox" id="ksef-person-other" name="billing_ksef_person_other" value="1"> <span>${CFG.label_person_other || 'Faktura na inne dane niż dane zamówienia'}</span></label>
				<div id="ksef-person-other-fields" style="display:none;margin-top:8px;">
					<input type="text" name="billing_ksef_person_name" placeholder="${CFG.label_person_name || 'Imię i nazwisko'}" style="width:100%;margin-bottom:6px;padding:8px 10px;border:1px solid #c3c4c7;border-radius:4px;">
					<input type="text" name="billing_ksef_person_street" placeholder="${CFG.label_person_street || 'Ulica i numer'}" style="width:100%;margin-bottom:6px;padding:8px 10px;border:1px solid #c3c4c7;border-radius:4px;">
					<div style="display:flex;gap:6px;">
						<input type="text" name="billing_ksef_person_zip" placeholder="${CFG.label_person_zip || 'Kod pocztowy'}" style="flex:0 0 40%;padding:8px 10px;border:1px solid #c3c4c7;border-radius:4px;">
						<input type="text" name="billing_ksef_person_city" placeholder="${CFG.label_person_city || 'Miejscowość'}" style="flex:1;padding:8px 10px;border:1px solid #c3c4c7;border-radius:4px;">
					</div>
				</div>
			</div>
		`;
		const cb = wrapper.querySelector('#ksef-request-invoice');
		const typeWrap = wrapper.querySelector('#ksef-invtype-wrapper');
		const typeSel = wrapper.querySelector('#ksef-invtype');
		const nipWrapper = wrapper.querySelector('#ksef-nip-wrapper');
		const personOther = wrapper.querySelector('#ksef-person-other');
		const apply = () => {
			const on = cb.checked;
			typeWrap.style.display = on ? '' : 'none';
			nipWrapper.style.display = ( on && typeSel.value !== 'person' ) ? '' : 'none';
			applyPersonSection(on && typeSel.value === 'person');
		};
		cb.addEventListener('change', apply);
		typeSel.addEventListener('change', apply);
		if (personOther) { personOther.addEventListener('change', apply); }
		attachGus(wrapper.querySelector('#ksef-nip-input'), wrapper.querySelector('#ksef-gus-result'));
		apply();
		return wrapper;
	}

	// Pobranie danych firmy z GUS po wpisaniu 10-cyfrowego NIP (gdy włączone w Pro z licencją).
	let gusTimer = null;
	function attachGus(input, box) {
		if (!input || input._ksefGusBound) return;
		input._ksefGusBound = true;
		const trigger = function(immediate){
			const nip = (input.value || '').replace(/\D+/g, '');
			if (gusTimer) clearTimeout(gusTimer);
			if (!CFG.gus_enabled || nip.length !== 10) { if (box) box.style.display = 'none'; return; }
			if (immediate) { doGusLookup(nip, box); } else { gusTimer = setTimeout(function(){ doGusLookup(nip, box); }, 600); }
		};
		input.addEventListener('input', function(){ trigger(false); });
		input.addEventListener('blur', function(){ trigger(true); }); // po odkliknięciu — pobierz od razu
	}
	// Stan edytowalnych danych nabywcy — przeżywa re-render Sellkita (IIFE ładuje się raz).
	var gusBuyer = { nip: '', name: '', street: '', zip: '', city: '', dirty: false };

	// Buduje (raz) edytowalny formularz danych firmy w boxie i przywraca wartości ze stanu.
	function ensureBuyerForm(box) {
		if (box._ksefForm) {
			var ff = box._ksefForm;
			ff.name.value = gusBuyer.name; ff.street.value = gusBuyer.street;
			ff.zip.value = gusBuyer.zip; ff.city.value = gusBuyer.city;
			return ff;
		}
		box.style.display = '';
		box.style.background = '#ecfdf3'; box.style.border = '1px solid #abefc6'; box.style.color = '#15803d';
		var inp = 'autocomplete="off" style="width:100%;display:block;margin-top:2px;padding:5px 7px;border:1px solid #abefc6;border-radius:4px;box-sizing:border-box;"';
		box.innerHTML =
			// Duży komunikat ładowania — widoczny dopóki nie ma danych z GUS.
			  '<div class="g-status" style="display:none;font-size:16px;font-weight:600;color:#15803d;padding:6px 2px;line-height:1.4;"></div>'
			// Pola — ukryte do czasu pobrania danych (klient nie widzi pustych pól w trakcie ładowania).
			+ '<div class="g-body" style="display:none;">'
			+   '<div class="g-hd" style="font-size:12px;color:#3f6212;margin-bottom:6px;"></div>'
			+   '<label style="display:block;font-size:11px;color:#3f6212;margin-bottom:6px;">Nazwa firmy<input type="text" name="billing_ksef_buyer_name" class="g-name" ' + inp + '></label>'
			+   '<label style="display:block;font-size:11px;color:#3f6212;margin-bottom:6px;">Ulica i numer<input type="text" name="billing_ksef_buyer_street" class="g-street" ' + inp + '></label>'
			+   '<div style="display:flex;gap:6px;">'
			+     '<label style="flex:0 0 40%;font-size:11px;color:#3f6212;">Kod pocztowy<input type="text" name="billing_ksef_buyer_zip" class="g-zip" ' + inp + '></label>'
			+     '<label style="flex:1;font-size:11px;color:#3f6212;">Miejscowość<input type="text" name="billing_ksef_buyer_city" class="g-city" ' + inp + '></label>'
			+   '</div>'
			+   '<div class="g-id" style="color:#3f6212;font-size:11px;margin-top:5px;"></div>'
			+   '<div class="g-note" style="font-size:11px;color:#65a30d;margin-top:5px;font-style:italic;"></div>'
			+ '</div>';
		var f = {
			status: box.querySelector('.g-status'), body: box.querySelector('.g-body'),
			hd: box.querySelector('.g-hd'),
			name: box.querySelector('.g-name'), street: box.querySelector('.g-street'),
			zip: box.querySelector('.g-zip'), city: box.querySelector('.g-city'),
			id: box.querySelector('.g-id'), note: box.querySelector('.g-note')
		};
		f.note.textContent = CFG.gus_invoice_note || 'Adres dostawy może być inny — to nie wpływa na fakturę.';
		f.name.value = gusBuyer.name; f.street.value = gusBuyer.street; f.zip.value = gusBuyer.zip; f.city.value = gusBuyer.city;
		var sync = function () {
			gusBuyer.name = f.name.value; gusBuyer.street = f.street.value;
			gusBuyer.zip = f.zip.value; gusBuyer.city = f.city.value; gusBuyer.dirty = true;
		};
		[f.name, f.street, f.zip, f.city].forEach(function (el) { el.addEventListener('input', sync); });
		box._ksefForm = f;
		return f;
	}

	async function doGusLookup(nip, box) {
		if (!box || !CFG.ajax_url) return;
		var f = ensureBuyerForm(box);
		box.style.display = '';
		// Dopóki pola nie były jeszcze pokazane — pokaż TYLKO duży komunikat ładowania (bez pustych pól).
		if (!box._ksefShown) {
			f.status.style.display = ''; f.status.textContent = CFG.gus_loading || 'Pobieram dane z GUS…';
			f.body.style.display = 'none';
		}
		try {
			const fd = new FormData();
			fd.append('action', 'ksef_checkout_gus');
			fd.append('nonce', CFG.gus_nonce || '');
			fd.append('nip', nip);
			const r = await fetch(CFG.ajax_url, { method: 'POST', body: fd, credentials: 'same-origin' });
			const j = await r.json();
			const d = (j && j.success && j.data && j.data.data) ? j.data.data : null;
			if (!d || !d.name) {
				// Brak w GUS — pokaż pola do ręcznego wpisania danych firmy.
				f.hd.textContent = (j && j.data && j.data.message) ? j.data.message : 'Nie znaleziono w GUS — wpisz dane firmy ręcznie:';
				f.status.style.display = 'none';
				f.body.style.display = '';
				box._ksefShown = true;
				return;
			}
			// Pre-fill z GUS tylko gdy użytkownik nie edytował lub zmienił NIP (nie nadpisujemy poprawek).
			if (!gusBuyer.dirty || gusBuyer.nip !== nip) {
				const lok = d.building_no ? (d.building_no + (d.flat_no ? '/' + d.flat_no : '')) : '';
				gusBuyer.name   = d.name;
				gusBuyer.street = (d.street ? (d.street + ' ' + lok) : lok).trim();
				gusBuyer.zip    = d.postal_code || '';
				gusBuyer.city   = d.city || '';
				gusBuyer.nip    = nip;
				gusBuyer.dirty  = false;
				f.name.value = gusBuyer.name; f.street.value = gusBuyer.street; f.zip.value = gusBuyer.zip; f.city.value = gusBuyer.city;
			}
			f.hd.textContent = CFG.gus_invoice_header || 'Faktura zostanie wystawiona na te dane (z GUS) — możesz poprawić:';
			const ids = [ 'NIP ' + (d.nip || nip) ];
			if (d.regon) { ids.push('REGON ' + d.regon); }
			f.id.textContent = ids.join(' · ');
			// Dane pobrane — pokaż wypełnione pola, schowaj komunikat.
			f.status.style.display = 'none';
			f.body.style.display = '';
			box._ksefShown = true;
		} catch (e) {
			f.hd.textContent = 'Nie udało się pobrać z GUS — możesz wpisać dane ręcznie:';
			f.status.style.display = 'none';
			f.body.style.display = '';
			box._ksefShown = true;
		}
	}

	function findEmailInput() {
		return document.querySelector('input[name="billing_email"]')
			|| document.querySelector('input[name="email"]')
			|| document.querySelector('input[type="email"]');
	}

	function alreadyInjected() {
		return !!document.querySelector('#ksef-nip-input')
			|| !!document.querySelector('input[name="billing_ksef_nip"]');
	}

	// NIP widoczny tylko gdy „Chcę fakturę VAT" zaznaczone. Wymuszamy !important — żeby CSS
	// motywu/innej wtyczki nie nadpisał ukrycia.
	function syncNipVisibility() {
		const cb = document.getElementById('ksef-request-invoice');
		const tw = document.getElementById('ksef-invtype-wrapper');
		const ts = document.getElementById('ksef-invtype');
		const w  = document.getElementById('ksef-nip-wrapper');
		if (!cb) return;
		if (tw) { tw.style.setProperty('display', cb.checked ? 'block' : 'none', 'important'); }
		if (w) {
			const showNip = cb.checked && (!ts || ts.value !== 'person');
			w.style.setProperty('display', showNip ? 'block' : 'none', 'important');
		}
		applyPersonSection(cb.checked && !!ts && ts.value === 'person');
	}

	// Pola PHP (woocommerce_checkout_fields: klasyczny / Sellkit / CartFlows) — gdy już są na
	// stronie, NIE wstrzykujemy drugiego kompletu, tylko podpinamy do nich ukrywanie + GUS.
	// Idempotentne (data-ksef-bound) i odporne na re-render (wywoływane ponownie z inject()).
	// Najwyższy wrapper danego pola, który NIE zawiera checkboxa (pełen wiersz pola) — żeby
	// ukrycie zwijało całą przestrzeń (label + input), nie tylko sam input.
	function wrapOf(el, cb) {
		let w = el;
		while (w.parentElement && w.parentElement !== document.body && !w.parentElement.contains(cb)) {
			w = w.parentElement;
		}
		return w;
	}

	// Sekcja faktury imiennej (osoba fizyczna): cała sekcja widoczna tylko gdy wybrano osobę;
	// pola „inne dane" — gdy zaznaczono checkbox „inne dane".
	function applyPersonSection(show) {
		const pf  = document.getElementById('ksef-person-fields');
		if (pf) { pf.style.setProperty('display', show ? 'block' : 'none', 'important'); }
		const po  = document.getElementById('ksef-person-other');
		const pof = document.getElementById('ksef-person-other-fields');
		if (pof) { pof.style.display = (show && po && po.checked) ? 'block' : 'none'; }
	}

	function bindPhpFields() {
		const cb  = document.getElementById('billing_ksef_request_invoice');
		const nip = document.getElementById('billing_ksef_nip');
		if (!cb || !nip) return false;
		const typeSel  = document.getElementById('billing_ksef_invoice_type');
		const wrap     = wrapOf(nip, cb);
		const typeWrap = typeSel ? wrapOf(typeSel, cb) : null;
		const isPerson = function(){ return typeSel && typeSel.value === 'person'; };
		const apply = function(){
			if (typeWrap) { typeWrap.style.setProperty('display', cb.checked ? 'block' : 'none', 'important'); }
			if (wrap) {
				const showNip = cb.checked && !isPerson();
				wrap.style.setProperty('display', showNip ? 'block' : 'none', 'important');
			}
			applyPersonSection(cb.checked && isPerson());
		};
		if (cb.getAttribute('data-ksef-bound') !== '1') {
			cb.setAttribute('data-ksef-bound', '1');
			cb.addEventListener('change', apply);
		}
		if (typeSel && typeSel.getAttribute('data-ksef-bound') !== '1') {
			typeSel.setAttribute('data-ksef-bound', '1');
			typeSel.addEventListener('change', apply);
		}
		const po = document.getElementById('ksef-person-other');
		if (po && po.getAttribute('data-ksef-bound') !== '1') {
			po.setAttribute('data-ksef-bound', '1');
			po.addEventListener('change', apply);
		}
		// GUS na polu PHP — box wyniku w wrapperze + lookup (attachGus jest idempotentne).
		if (wrap && !document.getElementById('ksef-gus-result')) {
			const gbox = document.createElement('div');
			gbox.id = 'ksef-gus-result';
			gbox.style.cssText = 'display:none;margin-top:8px;font-size:13px;line-height:1.45;padding:8px 10px;border-radius:4px;';
			wrap.appendChild(gbox);
		}
		attachGus(nip, document.getElementById('ksef-gus-result'));
		apply(); // stan początkowy + po każdym re-renderze
		return true;
	}

	// Czy to koszyk/checkout? — nie wstrzykuj na logowaniu/koncie/innych stronach z polem e-mail.
	function isCheckoutContext() {
		const cls = (document.body && document.body.className) || '';
		if (/woocommerce-(checkout|cart|order-pay)/.test(cls)) return true;
		return !!document.querySelector(
			'form.checkout, .woocommerce-checkout, .wc-block-checkout, .wc-block-cart,'
			+ ' [data-block-name="woocommerce/checkout"], [data-block-name="woocommerce/cart"],'
			+ ' #place_order, .wc-block-components-checkout-place-order-button, .cart_totals,'
			+ ' input[name="billing_address_1"], input[name="billing_city"], input[name="billing_postcode"], select[name="billing_country"]'
		);
	}

	function inject() {
		if (!isCheckoutContext()) return; // tylko koszyk/checkout
		// 1) Pola PHP już są (klasyczny/Sellkit/CartFlows) → podepnij do nich ukrywanie + GUS,
		//    bez wstrzykiwania drugiego kompletu pól.
		if (bindPhpFields()) return;
		// 2) Brak pól PHP (WooCommerce Blocks / Store API) → wstrzyknij własne pola.
		if (!document.getElementById('ksef-nip-input')) {
			const emailInput = findEmailInput();
			if (!emailInput) return;
			const formRow = emailInput.closest('.form-row, .wc-block-components-text-input, .woocommerce-input-wrapper, p, fieldset, div');
			if (!formRow) return;
			formRow.parentNode.insertBefore(buildField(), formRow.nextSibling);
		}
		// Re-asercja przy każdej mutacji DOM — w checkout blokowym/React listener bywa gubiony.
		syncNipVisibility();
	}

	// Inicjalny inject + mutacja DOM (dla react-based checkouts które renderują się asynchronicznie)
	function setup() {
		inject();
		// Delegowany listener (na document) — odporny na re-render i podmianę DOM.
		// Obsługuje zarówno wstrzyknięty checkbox, jak i checkbox z pól PHP.
		document.addEventListener('change', function(e){
			if (!e.target) return;
			if (e.target.id === 'ksef-request-invoice' || e.target.id === 'ksef-invtype' || e.target.id === 'ksef-person-other') { syncNipVisibility(); }
			if (e.target.name === 'billing_ksef_request_invoice' || e.target.name === 'billing_ksef_invoice_type' || e.target.name === 'billing_ksef_person_other') { bindPhpFields(); }
		});
		// Obserwuj TYLKO kontener checkoutu (nie całe body) — na body w edytorze/podglądzie
		// Elementora obserwator reagowałby na mutacje DOM edytora i mógł zapętlić/zawiesić stronę.
		const ksefDebInject = (function(){ let t; return function(){ clearTimeout(t); t = setTimeout(inject, 150); }; })();
		function ksefCheckoutRoot(){ return document.querySelector('form.checkout, form.woocommerce-checkout, .woocommerce-checkout, .wc-block-checkout, #sellkit-checkout, .sellkit-checkout, .sellkit-one-page-checkout-billing, .wcf-embed-checkout-form, .cartflows-checkout-form'); }
		function ksefAttachObs(){ const r = ksefCheckoutRoot(); if (!r) return false; try { new MutationObserver(ksefDebInject).observe(r, { childList: true, subtree: true }); } catch (e) {} return true; }
		if (!ksefAttachObs()) {
			// Checkout może renderować się asynchronicznie (Blocks/React). Lekki, czasowo ograniczony
			// obserwator body czeka na pojawienie się kontenera, podpina wąski obserwator i kończy.
			try {
				const bodyObs = new MutationObserver(function () { if (ksefAttachObs()) { try { bodyObs.disconnect(); } catch (e) {} ksefDebInject(); } });
				bodyObs.observe(document.body, { childList: true, subtree: true });
				setTimeout(function () { try { bodyObs.disconnect(); } catch (e) {} }, 10000);
			} catch (e) {}
		}

		// AJAX checkouts (Sellkit/CartFlows/Woo) przerenderowują pola — ponów po updated_checkout.
		// updated_checkout to zdarzenie jQuery (nie natywne DOM) — łapiemy je przez jQuery, jeśli jest.
		if (window.jQuery) {
			window.jQuery(document.body).on('updated_checkout wc_fragments_refreshed', inject);
		}
		document.addEventListener('updated_checkout', inject);
		document.addEventListener('wc_fragments_refreshed', inject);
		document.addEventListener('wc_blocks_checkout_block_loaded', inject);

		// Bezpiecznik: gdy formularz submitnie i NIP jest w DOM, dorzuć hidden input do każdej dziecięcej formy
		// (na wypadek gdyby form != form na którym field wisi)
		document.addEventListener('submit', function(e){
			const nipInput = document.getElementById('ksef-nip-input');
			const cb = document.getElementById('ksef-request-invoice');
			if (!nipInput || !cb || !e.target.tagName || e.target.tagName !== 'FORM') return;
			if (!e.target.contains(nipInput)) {
				appendHidden(e.target, 'billing_ksef_request_invoice', cb.checked ? '1' : '');
				appendHidden(e.target, 'billing_ksef_nip', nipInput.value);
				const ts = document.getElementById('ksef-invtype');
				appendHidden(e.target, 'billing_ksef_invoice_type', ts ? ts.value : 'company');
				const po = document.getElementById('ksef-person-other');
				appendHidden(e.target, 'billing_ksef_person_other', (po && po.checked) ? '1' : '');
				['name','street','zip','city'].forEach(function(k){
					const el = document.querySelector('input[name="billing_ksef_person_'+k+'"]');
					appendHidden(e.target, 'billing_ksef_person_'+k, el ? el.value : '');
				});
			}
		}, true);
	}

	function appendHidden(form, name, value) {
		if (form.querySelector(`input[name="${name}"]`)) return;
		const h = document.createElement('input');
		h.type = 'hidden'; h.name = name; h.value = value || '';
		form.appendChild(h);
	}

	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', setup);
	} else {
		setup();
	}
})();
