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 TRACKING_SCRIPT_NAME = 'CB AI Order Confirmation Tracking';

const getCdnAndApiUrls = () => {
	const cdnUrl = process.env.CDN_URL || '';
	const apiUrl = process.env.PRODUCT_WIDGET_API_URL || '';
	return { cdnUrl, apiUrl };
};

/**
 * Install or update the CB AI order confirmation tracking script via BigCommerce Content Scripts API.
 * Idempotent: creates script if missing, updates if exists (same name).
 * POST body: { storeHash } -> returns { scriptUuid, uniqueId }
 * DELETE body: { storeHash } -> removes the tracking script.
 */
export default async function installTrackingScript(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 tracking = scripts.find((s: any) => s.name === TRACKING_SCRIPT_NAME);
				if (tracking?.uuid) {
					await bigCommerce.delete(`/content/scripts/${tracking.uuid}`);
					return sendSuccessResponse(res, { removed: tracking.uuid }, 'Tracking script removed.');
				}
				return sendSuccessResponse(res, {}, 'No tracking script found.');
			} catch (err) {
				console.error('[installTrackingScript] DELETE error:', err);
				return sendFailedResponse(res, {}, 'Failed to remove tracking script.');
			}
		}

		// POST: install or update
		// Get uniqueId from bigcommerceCheck API
		let uniqueId = '';
		try {
			const checkResponse = await fetch(
				`${process.env.CBEND_URL}/api/v1/website/bigcommerceCheck`,
				{
					method: 'POST',
					headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
					body: JSON.stringify({
						storeHash,
						accessToken,
						productType: 'aiassistant'
					})
				}
			);
			if (checkResponse.ok) {
				const checkData = await checkResponse.json();
				if (checkData.status === 'success' && checkData.data?.uniqueId) {
					uniqueId = checkData.data.uniqueId;
				}
			}
		} catch (e) {
			console.error('[installTrackingScript] bigcommerceCheck error:', e);
		}
		if (!uniqueId) {
			return sendFailedResponse(res, {}, 'Could not get website uniqueId. Ensure the AI Product Assistant is set up for this store.');
		}

		const { cdnUrl, apiUrl } = getCdnAndApiUrls();
		if (!cdnUrl || !apiUrl) {
			return sendFailedResponse(res, {}, 'CDN_URL and PRODUCT_WIDGET_API_URL must be set.');
		}

		const scriptSrc = `${cdnUrl.replace(/\/$/, '')}/cb-ai-tracking.js`;
		const escapeHtmlAttr = (v: string) => String(v).replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
		// BigCommerce Script Manager replaces {{checkout.order.id}} with the order ID on order confirmation
		const html = `<script src="${escapeHtmlAttr(scriptSrc)}" data-cb-tracking-uuid="${escapeHtmlAttr(uniqueId)}" data-cb-tracking-api-url="${escapeHtmlAttr(apiUrl)}" data-cb-order-id="{{checkout.order.id}}" async></script>`;

		// List existing scripts and find ours by name
		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('[installTrackingScript] List scripts error:', err);
			return sendFailedResponse(res, {}, 'Failed to list store scripts.');
		}

		const scriptPayload = {
			name: TRACKING_SCRIPT_NAME,
			description: 'Sends order confirmation data to CB AI for conversion tracking.',
			html,
			auto_uninstall: true,
			load_method: 'default',
			location: 'footer',
			visibility: 'order_confirmation',
			kind: 'script_tag',
			consent_category: 'essential'
		};

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

		if (existing?.uuid) {
			// Script already installed: update it so store gets latest HTML (e.g. data-cb-order-id placeholder)
			await bigCommerce.put(`/content/scripts/${existing.uuid}`, scriptPayload);
			scriptUuid = existing.uuid;
			updated = true;
		} else {
			const createRes = await bigCommerce.post('/content/scripts', scriptPayload);
			const created = (createRes as any)?.data;
			scriptUuid = created?.uuid ?? created?.id ?? (createRes as any)?.uuid;
		}

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

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