import { NextApiRequest, NextApiResponse } from 'next';
import { bigcommerceClient } from '@lib/auth';
import { createWidgetTemplate, createWidget, createWidgetPlacement } from '@lib/bigcommerce';
import { sendSuccessResponse, sendBadResponse, sendFailedResponse, applicationErrorResponse } from '@lib/responses';
import BigCommerceSessions from '@database/models/BigCommerceSessions';
import { PRODUCT_ASSISTANT_WIDGET_V2 } from '@lib/productAssistantWidgetNames';
import { purgeBigCommerceProductAssistantWidget } from '@lib/purgeBigCommerceProductAssistantWidget';
import { productWidgetLog, productWidgetLogFile } from '@lib/productWidgetLogger';
import {
	DEFAULT_WIDGET_SETTINGS,
	DEFAULT_PLACEHOLDER,
	generateProductAssistantWidgetHtml,
	generateProductAssistantPageBuilderSchema,
	getProductAssistantCdnUrls,
	getProductBelowContentRegion,
	resolveProductPlacementTemplateFiles,
} from '@lib/productAssistantWidgetShared';

/**
 * POST /api/widgets/createProductWidgetV2
 *
 * Same body and behavior as createProductWidget, but:
 * - Injects `cb-ai-product-assistant-v2.js` (cron `/api/v2/chat/*` endpoints).
 * - Uses BigCommerce names `CB AI Product Assistant V2` so v1 and v2 widgets can coexist.
 * - If `PRODUCT_WIDGET_V2_API_URL` is set, it is used as `data-api-url`; otherwise `PRODUCT_WIDGET_API_URL`.
 *
 * Body: {
 *   storeHash,
 *   region?,
 *   templateFile? | customTemplate?,  // e.g. "pages/custom/product/custom-product" or "custom-product" (string or string[])
 *   title?, mainColor?, fontSize?, footerHtml?, headerIcon?, addToCartSelector?, addToCartQtySelector?
 * }
 */
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
	if (req.method !== 'POST') {
		return sendBadResponse(res, 'Method not allowed. Use POST');
	}

	try {
		const {
			storeHash,
			region: regionFromBody,
			templateFile: templateFileFromBody,
			customTemplate,
			title,
			mainColor,
			fontSize,
			footerHtml,
			headerIcon,
			addToCartSelector,
			addToCartQtySelector,
		} = req.body;

		const placementTemplateFiles = resolveProductPlacementTemplateFiles(
			templateFileFromBody,
			customTemplate
		);

		productWidgetLog.info('createProductWidgetV2 step 1: request received', {
			storeHash,
			regionFromBody,
			templateFileFromBody: templateFileFromBody || null,
			customTemplate: customTemplate || null,
			placementTemplateFiles,
			logFile: productWidgetLogFile,
		});

		if (!storeHash) {
			productWidgetLog.warn('createProductWidgetV2 step 1 failed: storeHash missing');
			return sendBadResponse(res, 'storeHash is required');
		}

		const widgetSettings = {
			title: title || DEFAULT_WIDGET_SETTINGS.title,
			mainColor: mainColor || DEFAULT_WIDGET_SETTINGS.mainColor,
			fontSize: fontSize || DEFAULT_WIDGET_SETTINGS.fontSize,
			footerHtml: footerHtml || DEFAULT_WIDGET_SETTINGS.footerHtml,
			headerIcon: headerIcon || DEFAULT_WIDGET_SETTINGS.headerIcon,
			addToCartSelector: addToCartSelector || DEFAULT_WIDGET_SETTINGS.addToCartSelector,
			addToCartQtySelector: addToCartQtySelector || DEFAULT_WIDGET_SETTINGS.addToCartQtySelector,
		};

		productWidgetLog.info('createProductWidgetV2 step 2: resolve store session', { storeHash });
		const bigCommerceSession = await BigCommerceSessions.findOne({ where: { storeHash } });

		if (!bigCommerceSession) {
			productWidgetLog.error('createProductWidgetV2 step 2 failed: store session not found', { storeHash });
			return sendFailedResponse(res, {}, 'Store session not found');
		}

		const accessToken = bigCommerceSession.dataValues.accessToken;
		const bigCommerce = bigcommerceClient(accessToken, storeHash, 'v3');
		productWidgetLog.info('createProductWidgetV2 step 2 done: BC client ready');

		productWidgetLog.info('createProductWidgetV2 step 3: fetch uniqueId from backend');
		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',
				}),
			});

			productWidgetLog.info('createProductWidgetV2 step 3: bigcommerceCheck response', {
				ok: checkResponse.ok,
				status: checkResponse.status,
			});

			if (checkResponse.ok) {
				const checkData = await checkResponse.json();
				if (checkData.status === 'success' && checkData.data?.uniqueId) {
					uniqueId = checkData.data.uniqueId;
				}
			}
		} catch (error: any) {
			productWidgetLog.error('createProductWidgetV2 step 3 error fetching uniqueId', {
				message: error?.message || String(error),
			});
		}

		if (!uniqueId) {
			productWidgetLog.error('createProductWidgetV2 step 3 failed: no uniqueId');
			return sendFailedResponse(res, {}, 'Failed to get uniqueId from backend');
		}
		productWidgetLog.info('createProductWidgetV2 step 3 done', { uniqueId });

		const templateName = PRODUCT_ASSISTANT_WIDGET_V2.templateName;
		const widgetName = PRODUCT_ASSISTANT_WIDGET_V2.widgetName;

		productWidgetLog.info('createProductWidgetV2 step 4: purge existing widget', {
			templateName,
			widgetName,
		});
		const purgeResult = await purgeBigCommerceProductAssistantWidget(bigCommerce, {
			templateName,
			widgetName,
		});
		productWidgetLog.info('createProductWidgetV2 step 4 done: purge result', purgeResult);

		productWidgetLog.info('createProductWidgetV2 step 5: resolve CDN / API URLs');
		const cdnUrls = getProductAssistantCdnUrls('cb-ai-product-assistant-v2.js', '[CreateProductWidgetV2]', true);
		const { scriptUrl, apiUrl } = cdnUrls;
		productWidgetLog.info('createProductWidgetV2 step 5 URLs', { scriptUrl, apiUrl });
		if (!scriptUrl || scriptUrl.includes('undefined')) {
			productWidgetLog.error('createProductWidgetV2 step 5 failed: invalid scriptUrl', { scriptUrl });
			return sendFailedResponse(res, {}, 'Script URL is not configured. Please set CDN_URL environment variable.');
		}
		if (!apiUrl || apiUrl.includes('undefined')) {
			productWidgetLog.error('createProductWidgetV2 step 5 failed: invalid apiUrl', { apiUrl });
			return sendFailedResponse(
				res,
				{},
				'API URL is not configured. Please set PRODUCT_WIDGET_API_URL or PRODUCT_WIDGET_V2_API_URL environment variable.'
			);
		}
		productWidgetLog.info('createProductWidgetV2 step 5 done');

		productWidgetLog.info('createProductWidgetV2 step 6: generate template HTML + schema');
		const templateHtml = generateProductAssistantWidgetHtml(uniqueId, storeHash, widgetSettings, cdnUrls);
		const schema = generateProductAssistantPageBuilderSchema();
		productWidgetLog.info('createProductWidgetV2 step 6 done', {
			htmlLength: templateHtml?.length ?? 0,
			settings: widgetSettings,
		});

		productWidgetLog.info('createProductWidgetV2 step 7: create widget template', { templateName });
		const templateUuid = await createWidgetTemplate(bigCommerce, templateName, templateHtml, schema, 'default');

		if (!templateUuid) {
			productWidgetLog.error('createProductWidgetV2 step 7 failed: no templateUuid');
			return sendFailedResponse(res, {}, 'Failed to create widget template');
		}
		productWidgetLog.info('createProductWidgetV2 step 7 done', { templateUuid });

		productWidgetLog.info('createProductWidgetV2 step 8: create widget instance', {
			widgetName,
			templateUuid,
		});
		const widgetConfiguration = {
			placeholder: DEFAULT_PLACEHOLDER,
		};
		const widgetUuid = await createWidget(bigCommerce, widgetName, templateUuid, widgetConfiguration);

		if (!widgetUuid) {
			productWidgetLog.error('createProductWidgetV2 step 8 failed: no widgetUuid');
			return sendFailedResponse(res, {}, 'Failed to create widget instance');
		}
		productWidgetLog.info('createProductWidgetV2 step 8 done', { widgetUuid });

		productWidgetLog.info('createProductWidgetV2 step 9: resolve product region', {
			regionFromBody: regionFromBody || null,
			placementTemplateFiles,
		});
		const primaryTemplateFile =
			placementTemplateFiles.find((f) => f !== 'pages/product') || placementTemplateFiles[0];
		const productRegion =
			typeof regionFromBody === 'string' && regionFromBody.trim() !== ''
				? regionFromBody.trim()
				: await getProductBelowContentRegion(bigCommerce, primaryTemplateFile);
		productWidgetLog.info('createProductWidgetV2 step 9 done', {
			productRegion,
			source: typeof regionFromBody === 'string' && regionFromBody.trim() !== '' ? 'request' : 'auto',
			primaryTemplateFile,
		});
		if (!productRegion) {
			productWidgetLog.warn(
				'createProductWidgetV2 step 9: no region — widget will be created but not placed automatically'
			);
		}

		productWidgetLog.info('createProductWidgetV2 step 10: delete existing placements for widget', {
			placementTemplateFiles,
		});
		try {
			const placementsResponse = await bigCommerce.get('/content/placements');
			if (placementsResponse?.data) {
				const existingPlacements = placementsResponse.data.filter(
					(p: any) =>
						p.widget_uuid === widgetUuid && placementTemplateFiles.includes(p.template_file)
				);
				productWidgetLog.info('createProductWidgetV2 step 10: existing placements', {
					count: existingPlacements.length,
					uuids: existingPlacements.map((p: any) => p.uuid),
				});

				for (const placement of existingPlacements) {
					try {
						await bigCommerce.delete(`/content/placements/${placement.uuid}`);
						productWidgetLog.info('createProductWidgetV2 step 10: deleted placement', {
							uuid: placement.uuid,
							templateFile: placement.template_file,
						});
					} catch (deleteError: any) {
						productWidgetLog.error('createProductWidgetV2 step 10: delete placement failed', {
							uuid: placement.uuid,
							message: deleteError?.message || String(deleteError),
						});
					}
				}
			} else {
				productWidgetLog.info('createProductWidgetV2 step 10: no placements data returned');
			}
		} catch (error: any) {
			productWidgetLog.error('createProductWidgetV2 step 10: fetch placements failed', {
				message: error?.message || String(error),
			});
		}
		productWidgetLog.info('createProductWidgetV2 step 10 done');

		const placements: Array<{
			templateFile: string;
			uuid: string | null;
			region: string | null;
			status: 'created' | 'failed' | 'skipped';
		}> = [];
		let placementUuid: string | null = null;

		if (productRegion) {
			for (const templateFile of placementTemplateFiles) {
				productWidgetLog.info('createProductWidgetV2 step 11: create placement', {
					widgetUuid,
					templateFile,
					region: productRegion,
				});
				const uuid = await createWidgetPlacement(
					bigCommerce,
					widgetUuid,
					templateFile,
					productRegion,
					'active',
					undefined,
					null
				);
				placements.push({
					templateFile,
					uuid,
					region: productRegion,
					status: uuid ? 'created' : 'failed',
				});
				if (uuid && !placementUuid) {
					placementUuid = uuid;
				}
				productWidgetLog.info('createProductWidgetV2 step 11 placement result', {
					templateFile,
					uuid,
				});
			}
		} else {
			productWidgetLog.warn('createProductWidgetV2 step 11 skipped: no productRegion');
			for (const templateFile of placementTemplateFiles) {
				placements.push({
					templateFile,
					uuid: null,
					region: null,
					status: 'skipped',
				});
			}
		}

		if (!placementUuid) {
			productWidgetLog.warn(
				'createProductWidgetV2: placement missing; user can add manually in Page Builder'
			);
		}

		productWidgetLog.info('createProductWidgetV2 done', {
			templateUuid,
			widgetUuid,
			placementUuid,
			region: productRegion,
			placements,
			placementTemplateFiles,
			logFile: productWidgetLogFile,
		});

		return sendSuccessResponse(
			res,
			{
				apiVersion: 'v2',
				templateUuid,
				widgetUuid,
				placementUuid,
				region: productRegion,
				templateFile: primaryTemplateFile,
				templateFiles: placementTemplateFiles,
				placements,
				templateName,
				widgetName,
				widgetSettings,
				scriptFile: 'cb-ai-product-assistant-v2.js',
				logFile: productWidgetLogFile,
				note: productRegion
					? `V2 widget created and placed on ${placements.filter((p) => p.status === 'created').length}/${placementTemplateFiles.length} template(s) in region: ${productRegion}. Uses /api/v2/chat on your API host.`
					: 'V2 widget created. Add via Page Builder if needed. Uses /api/v2/chat on your API host.',
			},
			'V2 widget created successfully'
		);
	} catch (error: any) {
		productWidgetLog.error('createProductWidgetV2 unhandled error', {
			message: error?.message || String(error),
			stack: error?.stack,
			logFile: productWidgetLogFile,
		});
		return applicationErrorResponse(res);
	}
}
