import type { NextApiRequest, NextApiResponse } from 'next';
import { bigcommerceClient } from '@lib/auth';
import { sendSuccessResponse, sendBadResponse, sendFailedResponse, applicationErrorResponse } from '@lib/responses';
import BigCommerceSessions from '@database/models/BigCommerceSessions';

const PRODUCT_DATA_SCRIPT_NAME = 'CB AI Product Page Data';

/**
 * Inline Script Manager snippet for product pages.
 * BC requires exactly one <script> tag in html (no {{#if}} wrappers, no {{json}}).
 * {{product.sku}} is the variant SKU; parent SKU is fetched via Storefront GraphQL before
 * conversionBoxAssistantProdData is set (sync XHR — no widget JS changes required).
 */
function generateProductDataScriptHtml(): string {
	return `<script data-cb-product-id="{{product.id}}" data-cb-product-name="{{product.title}}" data-cb-product-price="{{product.price.without_tax.value}}" data-cb-storefront-token="{{settings.storefront_api.token}}">(function(){var s=document.currentScript;if(!s)return;var id=Number(s.getAttribute("data-cb-product-id"))||0;if(!id)return;var sku="",tok=s.getAttribute("data-cb-storefront-token");if(tok){try{var x=new XMLHttpRequest();x.open("POST","/graphql",false);x.setRequestHeader("Content-Type","application/json");x.setRequestHeader("Authorization","Bearer "+tok);x.send(JSON.stringify({query:"query($productId:Int!){site{product(entityId:$productId){sku}}}",variables:{productId:id}}));if(x.status>=200&&x.status<300){var d=JSON.parse(x.responseText);sku=(d&&d.data&&d.data.site&&d.data.site.product&&d.data.site.product.sku)||""}}catch(e){}}window.conversionBoxAssistantProdData=window.conversionBoxAssistantProdData||{};window.conversionBoxAssistantProdData.product={id:id,sku:sku,name:s.getAttribute("data-cb-product-name")||"",price:Number(s.getAttribute("data-cb-product-price"))||0}})();</script>`;
}

/**
 * Install or update the CB AI product data script via BigCommerce Content Scripts API.
 * Idempotent: creates script if missing, updates if exists (same name).
 * POST body: { storeHash } -> returns { scriptUuid }
 * DELETE body: { storeHash } -> removes the product data script.
 */
export default async function installProductDataScript(req: NextApiRequest, res: NextApiResponse) {
	if (req.method !== 'POST' && req.method !== 'DELETE') {
		return res.setHeader('Allow', 'POST, DELETE').status(405).end();
	}

	try {
		const { storeHash } = req.body || {};
		if (!storeHash) {
			return sendBadResponse(res, 'storeHash is required');
		}

		const bigCommerceSession = await BigCommerceSessions.findOne({ where: { storeHash } });
		if (!bigCommerceSession) {
			return sendFailedResponse(res, {}, 'Store session not found');
		}

		const accessToken = (bigCommerceSession as any).dataValues?.accessToken ?? bigCommerceSession.accessToken;
		const bigCommerce = bigcommerceClient(accessToken, storeHash, 'v3');

		if (req.method === 'DELETE') {
			try {
				const listRes = await bigCommerce.get('/content/scripts');
				const scripts = (listRes as any)?.data ?? [];
				const productDataScript = scripts.find((s: any) => s.name === PRODUCT_DATA_SCRIPT_NAME);
				if (productDataScript?.uuid) {
					await bigCommerce.delete(`/content/scripts/${productDataScript.uuid}`);
					return sendSuccessResponse(res, { removed: productDataScript.uuid }, 'Product data script removed.');
				}
				return sendSuccessResponse(res, {}, 'No product data script found.');
			} catch (err) {
				console.error('[installProductDataScript] DELETE error:', err);
				return sendFailedResponse(res, {}, 'Failed to remove product data script.');
			}
		}

		const html = generateProductDataScriptHtml();

		let scripts: Array<{ uuid?: string; name?: string; [k: string]: unknown }> = [];
		try {
			const listRes = await bigCommerce.get('/content/scripts');
			scripts = (listRes as any)?.data ?? [];
		} catch (err) {
			console.error('[installProductDataScript] List scripts error:', err);
			return sendFailedResponse(res, {}, 'Failed to list store scripts.');
		}

		const scriptPayload = {
			name: PRODUCT_DATA_SCRIPT_NAME,
			description: 'Injects product id, sku, name, and price for CB AI Product Assistant on product pages.',
			html,
			auto_uninstall: true,
			load_method: 'default',
			location: 'head',
			visibility: 'storefront',
			kind: 'script_tag',
			consent_category: 'essential',
		};

		const existing = scripts.find((s: any) => s.name === PRODUCT_DATA_SCRIPT_NAME);
		let scriptUuid: string;
		let updated = false;

		if (existing?.uuid) {
			try {
				await bigCommerce.put(`/content/scripts/${existing.uuid}`, scriptPayload);
			} catch (err: any) {
				console.error('[installProductDataScript] Update script error:', err);
				const detail = err?.responseBody || err?.message || 'Failed to update product data script.';
				return sendFailedResponse(res, {}, typeof detail === 'string' ? detail : 'Failed to update product data script.');
			}
			scriptUuid = existing.uuid;
			updated = true;
		} else {
			try {
				const createRes = await bigCommerce.post('/content/scripts', scriptPayload);
				const created = (createRes as any)?.data;
				scriptUuid = created?.uuid ?? created?.id ?? (createRes as any)?.uuid;
			} catch (err: any) {
				console.error('[installProductDataScript] Create script error:', err);
				const detail = err?.responseBody || err?.message || 'Failed to create product data script.';
				return sendFailedResponse(res, {}, typeof detail === 'string' ? detail : 'Failed to create product data script.');
			}
		}

		if (!scriptUuid) {
			return sendFailedResponse(res, {}, 'Script created/updated but no UUID returned.');
		}

		const message = updated ? 'Product data script updated.' : 'Product data script installed.';
		return sendSuccessResponse(res, { scriptUuid, updated }, message);
	} catch (error: any) {
		console.error('[installProductDataScript] Error:', error);
		return applicationErrorResponse(res);
	}
}
