import { Injectable, Logger } from '@nestjs/common';
import { EnglishLanguageService } from './services/english-language/english-language.service';
import { HebrewLanguageService } from './services/hebrew-language/hebrew-language.service';
import { ArabicLanguageService } from './services/arabic-language/arabic-language.service';
import envConfig from 'src/common/config/envConfig';
import { GOOGLE_LANGUAGE_CODES, LANGUAGE_CONFIG } from './language.config';
import { IDataToReturn, ILanguageType, Language } from './language.interface';
import { ChatGptService } from '../third-party/services/chat-gpt/chat-gpt.service';

@Injectable()
export class LanguageService {

	private readonly logger = new Logger(LanguageService.name)


	// async onModuleInit() {
	// 	const res = await this.translateText('שלום');
	// 	console.log(res);
	// }

	constructor(
		private readonly englishLanguageService: EnglishLanguageService,
		private readonly hebrewLanguageService: HebrewLanguageService,
		private readonly arabicLanguageService: ArabicLanguageService,
		private readonly chatGptService: ChatGptService,
	) { }

	// async onModuleInit() {
	// 	const res = await this.translateText('hello', 'he');
	// 	console.log(res);
	// }

	async translateText(text: string, languageToTranslate?: Language): Promise<IDataToReturn> {

		// by default for now NOT USING this service
		return {
			originalContent: text,
			translatedContent: text,
			originalLanguage: Language.EN,
			translatedLanguage: Language.EN,
		}

		const detectedGoogleLang = this.detectLanguage(text);
		const originalLanguage = detectedGoogleLang === 'he' ? Language.HB : Language.EN;

		// console.log('Language Detected => ', detectedGoogleLang);
		this.logger.log('Language Detected => ' + detectedGoogleLang + ', converted to: ' + originalLanguage);

		let dataToReturn: IDataToReturn = {
			originalContent: text,
			translatedContent: '',
			originalLanguage: originalLanguage,
			translatedLanguage: Language.EN,
		}

		if (!languageToTranslate) {
			switch (detectedGoogleLang) {
				case GOOGLE_LANGUAGE_CODES.he:
					dataToReturn.translatedContent = await this.translateToEnglish(text);
					break;
				case GOOGLE_LANGUAGE_CODES.ar:
					dataToReturn.translatedContent = await this.translateToEnglish(text);
					break;
				default:
					dataToReturn.translatedContent = text;
					break;
			}
		}
		else {
			switch (languageToTranslate) {
				case Language.HB:
					dataToReturn.translatedContent = await this.translateEnglishToDiffLanguage(text, 'he');
					dataToReturn.translatedLanguage = Language.HB;
					break;
				case Language.EN:
					dataToReturn.translatedContent = text;
					dataToReturn.translatedLanguage = Language.EN;
					break;
				default:
					dataToReturn.translatedContent = text;
					break;
			}
		}

		return dataToReturn
	}

	async translateText_v2(text: string, languageToTranslate?: Language): Promise<IDataToReturn> {

		const detectedGoogleLang = this.detectLanguage(text);
		const originalLanguage = detectedGoogleLang === 'he' ? Language.HB : Language.EN;

		// console.log('Language Detected => ', detectedGoogleLang);
		this.logger.log('Language Detected => ' + detectedGoogleLang + ', converted to: ' + originalLanguage);

		let dataToReturn: IDataToReturn = {
			originalContent: text,
			translatedContent: '',
			originalLanguage: originalLanguage,
			translatedLanguage: Language.EN,
		}

		if (!languageToTranslate) {
			switch (detectedGoogleLang) {
				case GOOGLE_LANGUAGE_CODES.he:
					dataToReturn.translatedContent = await this.translateToEnglish(text);
					break;
				case GOOGLE_LANGUAGE_CODES.ar:
					dataToReturn.translatedContent = await this.translateToEnglish(text);
					break;
				default:
					dataToReturn.translatedContent = text;
					break;
			}
		}
		else {
			switch (languageToTranslate) {
				case Language.HB:
					dataToReturn.translatedContent = await this.translateEnglishToDiffLanguage(text, 'he');
					dataToReturn.translatedLanguage = Language.HB;
					break;
				case Language.EN:
					dataToReturn.translatedContent = text;
					dataToReturn.translatedLanguage = Language.EN;
					break;
				default:
					dataToReturn.translatedContent = text;
					break;
			}
		}

		return dataToReturn
	}


	async translateText_v3_using_gpt(text: string): Promise<IDataToReturn> {

		const detectedGoogleLang = this.detectLanguage(text);
		const originalLanguage = detectedGoogleLang === 'he' ? Language.HB : Language.EN;

		// console.log('Language Detected => ', detectedGoogleLang);
		this.logger.log('Language Detected => ' + detectedGoogleLang + ', converted to: ' + originalLanguage);

		let dataToReturn: IDataToReturn = {
			originalContent: text,
			translatedContent: '',
			originalLanguage: originalLanguage,
			translatedLanguage: Language.EN,
		}

		if(detectedGoogleLang === GOOGLE_LANGUAGE_CODES.en) {
			dataToReturn.translatedContent = text;
			return dataToReturn;
		}


		// call gpt service for getting better translated prompt for image generation
		const gptInstruction = `${text}
		- given the following image generation prompt in hebrew - provide a detailed prompt in english that can be understood by a image generation module - do not answer with any other context besides the improved prompt`

		const gptResponse = await this.chatGptService.generateChatbotResponse({
			messages: [
				{
					role: 'system',
					content: gptInstruction
				}
			]
		})

		console.log("Image Generation Prompt => ", text);
		const gptResponsePrompt = gptResponse.choices?.[0]?.message?.content || text;

		console.log('GPT Response => ', gptResponsePrompt);
		
		// Remove inverted commas from the title if any
		dataToReturn.translatedContent = gptResponsePrompt.replace(/"/g, '');

		// Remove the Title: prefix from the title if any (Title: is added by the AI
		dataToReturn.translatedContent = dataToReturn.translatedContent.replace(/title:/gi, '');



		return dataToReturn
	}

	isHebrew(text: string) {
		return /[\u0590-\u05FF]/.test(text);
	}

	private detectLanguage(text: string): ILanguageType {
		switch (true) {
			case LANGUAGE_CONFIG.hebrew.regex.test(text):
				return GOOGLE_LANGUAGE_CODES.he;
			case LANGUAGE_CONFIG.arabic.regex.test(text):
				return GOOGLE_LANGUAGE_CODES.ar;
			default:
				return GOOGLE_LANGUAGE_CODES.en;
		}
	}

	private async translateEnglishToDiffLanguage(text: string, languageToTranslate: ILanguageType): Promise<string> {

		const { TranslationServiceClient } = require('@google-cloud/translate');
		const client = new TranslationServiceClient({
			credentials: JSON.parse(Buffer.from(`${envConfig().GOOGLE_SERVICE_ACOUNT_BASE64}`, 'base64').toString()),
		});

		const projectId = 'instant-maxim-429116-s2';
		const location = 'global';
		const parent = `projects/${projectId}/locations/${location}`;
		const request = {
			parent: parent,
			contents: [text],
			mimeType: 'text/plain', // mime types: text/plain, text/html
			sourceLanguageCode: 'en-US',
			targetLanguageCode: languageToTranslate,
		};

		const [response] = await client.translateText(request);
		return response.translations[0].translatedText;
	}

	private async translateToEnglish(text: string): Promise<string> {

		const { TranslationServiceClient } = require('@google-cloud/translate');
		const client = new TranslationServiceClient({
			credentials: JSON.parse(Buffer.from(`${envConfig().GOOGLE_SERVICE_ACOUNT_BASE64}`, 'base64').toString()),
		});

		const projectId = 'instant-maxim-429116-s2';
		const location = 'global';
		const parent = `projects/${projectId}/locations/${location}`;
		const request = {
			parent: parent,
			contents: [text],
			mimeType: 'text/plain', // mime types: text/plain, text/html
			sourceLanguageCode: this.detectLanguage(text),
			targetLanguageCode: 'en-US',
		};

		const [response] = await client.translateText(request);
		return response.translations[0].translatedText;
	}

}