'use client';

import { useEffect, useState, ReactNode, useRef, useMemo } from 'react';
import { useLocale } from '@/contexts/LocaleContext';

// Cache global de traduções
const translationCache = new Map<string, string>();

// Função para traduzir texto via API (requisição individual)
async function translateText(text: string, targetLang: string): Promise<string> {
  if (!text || text.trim() === '') return text;
  
  const cacheKey = `pt:${targetLang}:${text}`;
  
  // Cache hit: retorna imediatamente
  if (translationCache.has(cacheKey)) {
    return translationCache.get(cacheKey)!;
  }

  try {
    const response = await fetch('/api/translate', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ text, source: 'pt', target: targetLang }),
    });

    if (response.ok) {
      const data = await response.json();
      const translated = data.translatedText || text;
      translationCache.set(cacheKey, translated);
      return translated;
    }
  } catch (error) {
    console.error('[T] Translation error:', error);
  }

  return text;
}

// Função para traduzir múltiplos textos de uma vez (BATCH - muito mais rápido)
async function translateBatchTexts(texts: string[], targetLang: string): Promise<string[]> {
  if (!texts.length) return texts;
  
  // Verificar quais já estão em cache
  const results: string[] = new Array(texts.length);
  const toTranslate: { index: number; text: string }[] = [];
  
  texts.forEach((text, i) => {
    if (!text || text.trim() === '') {
      results[i] = text || '';
      return;
    }
    
    const cacheKey = `pt:${targetLang}:${text}`;
    if (translationCache.has(cacheKey)) {
      results[i] = translationCache.get(cacheKey)!;
    } else {
      toTranslate.push({ index: i, text });
    }
  });
  
  // Se todos estão em cache, retorna direto
  if (toTranslate.length === 0) {
    return results;
  }
  
  // Traduzir os que faltam via batch API
  try {
    const response = await fetch('/api/translate', {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ 
        texts: toTranslate.map(t => t.text), 
        source: 'pt', 
        target: targetLang 
      }),
    });

    if (response.ok) {
      const data = await response.json();
      const translations = data.translations || [];
      
      toTranslate.forEach((item, idx) => {
        const translated = translations[idx] || item.text;
        results[item.index] = translated;
        translationCache.set(`pt:${targetLang}:${item.text}`, translated);
      });
    } else {
      // Fallback: usar textos originais
      toTranslate.forEach(item => {
        results[item.index] = item.text;
      });
    }
  } catch (error) {
    console.error('[T] Batch translation error:', error);
    toTranslate.forEach(item => {
      results[item.index] = item.text;
    });
  }
  
  return results;
}

interface AutoTranslateProps {
  children: ReactNode;
  as?: 'span' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'div' | 'li' | 'label';
  className?: string;
}

/**
 * Componente que traduz texto automaticamente via LibreTranslate
 * Uso: <T>Texto em português</T>
 */
export function T({ children, as = 'span', className }: AutoTranslateProps) {
  const { locale } = useLocale();
  
  // Converter children para string de forma estável
  const originalText = useMemo(() => {
    return typeof children === 'string' ? children : String(children || '');
  }, [children]);
  
  const [translatedText, setTranslatedText] = useState(originalText);
  const lastTranslatedRef = useRef<{ text: string; lang: string } | null>(null);

  useEffect(() => {
    console.log('[T] useEffect - locale:', locale, 'text:', originalText.substring(0, 20));
    
    // Se idioma é PT, mostrar texto original
    if (locale === 'pt') {
      setTranslatedText(originalText);
      lastTranslatedRef.current = null;
      return;
    }

    // Evitar tradução duplicada
    if (
      lastTranslatedRef.current?.text === originalText &&
      lastTranslatedRef.current?.lang === locale
    ) {
      console.log('[T] Pulando - já traduzido');
      return;
    }

    // Verificar cache primeiro (síncrono)
    const cacheKey = `pt:${locale}:${originalText}`;
    if (translationCache.has(cacheKey)) {
      console.log('[T] Cache hit:', originalText.substring(0, 20));
      setTranslatedText(translationCache.get(cacheKey)!);
      lastTranslatedRef.current = { text: originalText, lang: locale };
      return;
    }

    console.log('[T] Chamando API para:', originalText.substring(0, 20));
    let cancelled = false;

    translateText(originalText, locale).then((result) => {
      console.log('[T] Resultado:', result.substring(0, 20));
      if (!cancelled) {
        setTranslatedText(result);
        lastTranslatedRef.current = { text: originalText, lang: locale };
      }
    });

    return () => {
      cancelled = true;
    };
  }, [originalText, locale]);

  const Tag = as;
  return <Tag className={className}>{translatedText}</Tag>;
}

// Alias para uso mais curto
export const AutoTranslate = T;

/**
 * Hook para traduzir texto programaticamente
 */
export function useTranslate() {
  const { locale } = useLocale();
  const [isTranslating, setIsTranslating] = useState(false);

  const translate = async (text: string): Promise<string> => {
    if (!text || locale === 'pt') return text;

    setIsTranslating(true);
    try {
      const result = await translateText(text, locale);
      return result;
    } finally {
      setIsTranslating(false);
    }
  };

  const translateBatch = async (texts: string[]): Promise<string[]> => {
    if (locale === 'pt') return texts;

    setIsTranslating(true);
    try {
      const results = await Promise.all(
        texts.map(text => translateText(text, locale))
      );
      return results;
    } finally {
      setIsTranslating(false);
    }
  };

  return { translate, translateBatch, isTranslating, locale };
}

/**
 * Hook para traduzir conteúdo do banco de dados
 */
export function useTranslatedContent<T extends Record<string, unknown>>(content: T | null): {
  translatedContent: T | null;
  isTranslating: boolean;
} {
  const { locale } = useLocale();
  const [translatedContent, setTranslatedContent] = useState<T | null>(content);
  const [isTranslating, setIsTranslating] = useState(false);

  useEffect(() => {
    if (!content || locale === 'pt') {
      setTranslatedContent(content);
      return;
    }

    let cancelled = false;
    const targetLang = locale;

    const translateContent = async () => {
      setIsTranslating(true);

      // Extrair todos os textos do objeto
      const texts: string[] = [];
      const paths: string[] = [];

      const extractTexts = (obj: unknown, path: string = '') => {
        if (typeof obj === 'string' && obj.length > 0 && obj.length < 5000) {
          texts.push(obj);
          paths.push(path);
        } else if (Array.isArray(obj)) {
          obj.forEach((item, index) => extractTexts(item, `${path}[${index}]`));
        } else if (obj && typeof obj === 'object') {
          Object.entries(obj).forEach(([key, value]) => {
            // Ignorar campos que não devem ser traduzidos
            if (['icon', 'image', 'img', 'url', 'href', 'id', 'slug'].includes(key)) return;
            extractTexts(value, path ? `${path}.${key}` : key);
          });
        }
      };

      extractTexts(content);

      if (texts.length === 0) {
        setIsTranslating(false);
        return;
      }

      try {
        // Traduzir todos os textos
        const translations = await Promise.all(
          texts.map(text => translateText(text, targetLang))
        );

        if (cancelled) return;

        // Reconstruir objeto com traduções
        const newContent = JSON.parse(JSON.stringify(content));

        paths.forEach((path, index) => {
          const parts = path.replace(/\[(\d+)\]/g, '.$1').split('.');
          let current: Record<string, unknown> = newContent;

          for (let i = 0; i < parts.length - 1; i++) {
            current = current[parts[i]] as Record<string, unknown>;
          }

          current[parts[parts.length - 1]] = translations[index];
        });

        setTranslatedContent(newContent);
      } catch (error) {
        console.error('Translation error:', error);
      } finally {
        if (!cancelled) {
          setIsTranslating(false);
        }
      }
    };

    translateContent();

    return () => {
      cancelled = true;
    };
  }, [content, locale]);

  return { translatedContent, isTranslating };
}
