import { Client } from 'typesense';
import { optional } from 'zod';

export const createTypeSenseClient	= async(typeSenseConfig:any) => {
	const client = new Client({
							nodes: [
								{
									host: typeSenseConfig.host,
									port: typeSenseConfig.port,
									protocol: typeSenseConfig.protocol,
								},
							],
							apiKey: typeSenseConfig.adminAPIKey,
							connectionTimeoutSeconds: 60000
						});
	return client;
}

export const createTypesenseSchema = async(typeSenseConfig:any) => {
	try{
		let client = await createTypeSenseClient(typeSenseConfig),
			productCollectionName	= typeSenseConfig.tablePrefix+typeSenseConfig.websiteId+"_products",
			schema:any = {
							name: productCollectionName,
							enable_nested_fields: true,
							fields: [
								{name: 'id', type: 'int32'},
								{name: 'title', type: 'string', optional: true},							
								{name: 'name', type: 'string', sort : true, optional: true},
								{name: 'type', type: 'string', facet: true, optional: true},
								{name: 'sku', type: 'string', optional: true},
								{name: 'nameNormalized', type: 'string', infix: true, optional: true},
								{name: 'skuNormalized', type: 'string', infix: true, optional: true},
								{name: 'upc', type: 'string', optional: true},
								{name: 'url', type: 'string', optional: true},
								{name: 'image', type: 'string', optional: true},
								{name: 'mobileImage', type: 'string', optional: true },
								{name: 'bannerSize', type: 'string', optional: true },
								{name: 'isBanner', type: 'int32', optional: true, facet: true },
								{name: "duplicateBanner", type: "int32", optional: true, facet: true},
								{name: 'product_images', type: 'string[]', optional: true},
								{name: 'channel_ids', type: 'int32[]', facet: true, optional: true},
								{name: 'categories', type: 'string[]', facet: true, optional: true},
								{name: 'category_ids', type: 'int32[]', facet: true, optional: true},
								{name: 'category_full_path', type: 'string[]', facet: true, optional: true},
								{name: 'created_at', type: 'int32', sort : true, optional: true},
								{name: 'stock_qty', type: 'int32', sort : true, optional: true},
								{name: 'price', type: 'float', facet: true,sort : true, optional: true},
								{name: 'effective_price', type: 'float', facet: true,sort : true, optional: true},
								{name: 'cost_price', type: "float", sort: true, optional: true},
								{name: 'retail_price', type: 'float', facet: true, sort : true, optional: true},
								{name: 'sale_price', type: 'float', facet: true, sort : true, optional: true},
								{name: 'calculated_price', type: 'float', facet: true, sort: true, optional: true},
								{name: 'is_visible', type: 'int32', facet: true, optional: true},
								{name: 'is_featured', type: 'int32', facet: true, optional: true},
								{name: 'availability', type: 'string', facet: true, optional: true},
								{name: 'isPriceHidden', type: 'int32', facet: true, optional: true},
								{name: 'priceHiddenLabel', type: 'string', optional: true},
								{name: 'weight', type: 'float', facet: true, sort: true, optional: true},
								{name: 'width', type: 'float', facet: true, sort: true, optional: true},
								{name: 'depth', type: 'float', facet: true, sort: true, optional: true},
								{name: 'height', type: 'float', facet: true, sort: true, optional: true},
								{name: "inventory_tracking", type: "string", optional: true},
								{name: "in_stock", type: "int32", facet: true, optional: true },
								{name: 'description', type: 'string', optional: true},
								{name: 'variant_ids', type: 'int32[]', optional: true},
								{name: 'total_variants', type: 'int32', optional: true},
								{name: 'brand', type: 'string', sort: true, facet: true, optional: true},
								{name: 'brandId', type: 'int32', optional: true, facet: true, sort: true},
								{name: 'option_names', type: 'string[]', optional: true},
								{name: 'options', type: "object", facet: true, optional: true},
								{name: 'available_options', type: "object", facet: true, optional: true},
								{name: 'custom_fields', type: "object", optional: true, facet: true},
								{name: 'cumulativeSales', type: 'int32', optional: true, facet: true, sort: true},
								{name: 'recentSales', type: 'int32', optional: true, facet: true, sort: true},
								{name: 'categories_full_path', type: 'string[]', optional: true, facet: true},
								{name: 'searchKeywords', type: 'string', optional: true },
								{name: 'reviews', type: 'int32', facet: true, optional: true},
								{name: 'no_of_reviews', type: 'int32', optional: true},
								{name: 'review_score', type: 'float', facet: true, optional: true},
							]					
						}
		client.collections().create(schema)
		.then(response => {
			let categoryCollectionName	= typeSenseConfig.tablePrefix+typeSenseConfig.websiteId+"_category",
				categorySchema:any	= {
												name: categoryCollectionName,
												enable_nested_fields: true,
												fields: [
													{name: 'id', type: "int32"},
													{name: 'name', type: "string"},
													{name: 'url', type: "string"},
													{name: 'full_path', type: 'string', optional: true, facet: true},
													{name: 'parent_id', type: 'int32', optional: true, facet: true},
													{name: 'channel_id', type: 'int32', facet: true},
													{name: 'is_visible', type: 'int32', facet: true},
													{name: 'image_url', type: 'string'}
												]
											}
			client.collections().create(categorySchema)
			.then(response => {
				console.log('Collection created:', response);
			}).catch(error => {
				console.log(typeof error)
				console.error('Error creating collection:', error);
			})
		}).catch(error => {
			console.log(typeof error)
			console.error('Error creating collection:', error);
		})
	}catch(e){
		console.log(e)
	}
}

export const createPageTypesenseSchema	= async(typeSenseConfig:any) => {
	try{
		let client = await createTypeSenseClient(typeSenseConfig),
			pageCollectionName	= typeSenseConfig.tablePrefix+typeSenseConfig.websiteId+"_pages",
			schema:any = {
								name: pageCollectionName,
								fields: [
									{name: 'id', type: 'int32'},			
									{name: 'name', type: 'string', sort : true},
									{name: 'description', type: 'string'},
									{name: 'channel_id', type: 'int32', facet: true},
									{name: "is_visible", type: 'int32', facet: true},
									{name: 'sort_order', type: 'int32', sort: true},
									{name: "url", type: "string"}
								]					
							}
		client.collections().create(schema)
		.then(response => {
			console.log('Collection created:', response);
		}).catch(error => {
			console.log(typeof error)
			console.error("Error creating collection:", error)
		})
	}catch(e){
		console.log(e)
	}
}

export const createBlogTypesenseSchema	= async(typeSenseConfig:any) => {
	try{
		let client = await createTypeSenseClient(typeSenseConfig),
			blogCollectionName	= typeSenseConfig.tablePrefix+typeSenseConfig.websiteId+"_blogs",
			schema:any = {
								name: blogCollectionName,
								fields: [
									{name: 'id', type: 'int32'},			
									{name: 'name', type: 'string', sort : true},
									{name: 'description', type: 'string'},
									{name: 'author', type: 'string'},
									{name: "is_published", type: 'int32', facet: true},
									{name: "url", type: "string"},
									{name: "thumbnail_path", type: "string"},
									{name: "tags", type: "string[]", facet: true},
									{name: "published_date", type: "int32"}
								]					
							}
		client.collections().create(schema)
		.then(response => {
			console.log('Collection created:', response);
		}).catch(error => {
			console.log(typeof error)
			console.error("Error creating collection:", error)
		})
	}catch(e){
		console.log(e)
	}
}

export const createQuerySuggestionTypesenseSchema	= async(typeSenseConfig:any) => {
	try{
		let client = await createTypeSenseClient(typeSenseConfig),
			queriesCollectionName	= typeSenseConfig.tablePrefix+typeSenseConfig.websiteId+"_queries",
			productCollectionName	= typeSenseConfig.tablePrefix+typeSenseConfig.websiteId+"_products",
			ruleName						= typeSenseConfig.tablePrefix+typeSenseConfig.websiteId+"_queries_aggregation",
			schema:any = {
								name: queriesCollectionName,
								fields: [
									{name: "q", type: "string" },
									{name: "count", type: "int32" }
								]
							}
		client.collections().create(schema)
		let ruleConfiguration = {
											type: "popular_queries",
											params: {
												source: {
													collections: [productCollectionName]
												},
												destination: {
													collection: queriesCollectionName
												},
												expand_query: true,
												limit: 10000
											}
										};
		(client.analytics.rules() as any).upsert(ruleName, ruleConfiguration)
	}catch(e){
		console.log(e)
	}
}

export const createBannerTypesenseSchema	= async(typeSenseConfig:any) => {
	try{
		let client = await createTypeSenseClient(typeSenseConfig),
			bannerCollectionName	= typeSenseConfig.tablePrefix+typeSenseConfig.websiteId+"_banners",
			schema:any = {
								name: bannerCollectionName,
								fields: [
									{name: 'id', type: 'string'},			
									{name: 'title', type: 'string', sort : true},
									{name: 'type', type: 'string', facet: true},
									{name: 'createdAt', type: 'int32', sort: true}
								]
							}
		client.collections().create(schema)
		.then(response => {
			console.log('Collection created:', response);
		}).catch(error => {
			console.log(typeof error)
			console.error("Error creating collection:", error)
		})
	}catch(e){
		console.log(e)
	}
}