import { useEffect, useMemo, useRef, useState } from 'react';
import {
  Alert,
  Box,
  Button,
  LinearProgress,
  Stack,
  Typography,
} from '@mui/material';
import { useNavigate } from 'react-router-dom';
import Tesseract from 'tesseract.js';
import { useAppStore } from '../store/useAppStore';
import { correctTurkishCharacters } from '../utils/ocrUtils';
import { translateChunkToTurkish } from '../utils/translationUtils';

const OcrStep = () => {
  const navigate = useNavigate();
  const isDev = import.meta.env.DEV;
  const croppedImages = useAppStore((state) => state.croppedImages);
  const ocrText = useAppStore((state) => state.ocrText);
  const setOcrText = useAppStore((state) => state.setOcrText);
  const setError = useAppStore((state) => state.setError);
  const translatedText = useAppStore((state) => state.translatedText);
  const translationStatus = useAppStore((state) => state.translationStatus);
  const translationError = useAppStore((state) => state.translationError);
  const translationProgress = useAppStore((state) => state.translationProgress);
  const setTranslatedText = useAppStore((state) => state.setTranslatedText);
  const setTranslationStatus = useAppStore((state) => state.setTranslationStatus);
  const setTranslationError = useAppStore((state) => state.setTranslationError);
  const setTranslationProgress = useAppStore((state) => state.setTranslationProgress);
  const clearTranslation = useAppStore((state) => state.clearTranslation);
  const [status, setStatus] = useState('idle');
  const [translationTrigger, setTranslationTrigger] = useState(0);
  const [currentIndex, setCurrentIndex] = useState(0);
  const [previewText, setPreviewText] = useState('');
  const total = croppedImages.length;
  const hasResults = useMemo(() => Boolean(ocrText?.length), [ocrText]);
  const abortRef = useRef(false);

  const assetBase = useMemo(() => {
    const rawBase = import.meta.env.BASE_URL ?? '/';
    if (rawBase === '.' || rawBase === './' || rawBase === '/') {
      return '';
    }
    return rawBase.endsWith('/') ? rawBase.slice(0, -1) : rawBase;
  }, []);
  const workerRef = useRef(null);
  const [workerReady, setWorkerReady] = useState(false);
  const previewRef = useRef(null);
  const translationPreviewRef = useRef(null);

  const orderedImages = useMemo(
    () => [...croppedImages].sort((a, b) => (a.order ?? 0) - (b.order ?? 0)),
    [croppedImages],
  );

  useEffect(() => {
    if (!orderedImages.length) return undefined;
    let cancelled = false;
    const origin =
      typeof window !== 'undefined' ? window.location.origin : '';
    const prefix = `${origin}${assetBase}`;
    const paths = {
      workerPath: `${prefix}/tesseract/worker.min.js`,
      corePath: `${prefix}/tesseract/tesseract-core-simd-lstm.wasm.js`,
      langPath: `${prefix}/tesseract`,
    };

    const initWorker = async () => {
      setWorkerReady(false);
      try {
        const workerOptions = {
          workerPath: paths.workerPath,
          corePath: paths.corePath,
          langPath: paths.langPath,
        };
        if (isDev) {
          workerOptions.logger = (m) => console.log('Tesseract:', m);
        }
        const worker = await Tesseract.createWorker(
          'tur',  // Dil doğrudan belirt
          1,      // OEM level (LSTM)
          workerOptions,
        );

        // Türkçe karakter tanımını iyileştir
        await worker.setParameters({
          tessedit_char_whitelist: 'abcçdefgğhıijklmnoöprsştuüvyzâîûABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZÂÎÛ0123456789 .,;:!?\'"-_',
          tessedit_pageseg_mode: '6', // Tek bir metin bloğu varsay
          preserve_interword_spaces: '1',
        });
        if (cancelled) {
          await worker.terminate();
          return;
        }
        // Dil ve worker zaten createWorker sırasında yüklendi
        if (isDev) {
          console.log('Tesseract worker başarıyla oluşturuldu');
        }
        workerRef.current = worker;
        setWorkerReady(true);
      } catch (error) {
        console.error('Tesseract başlatma hatası:', error);
        let errorMessage;

        if (error.message.includes('traineddata')) {
          errorMessage = 'Tesseract dil dosyaları bulunamadı. Lütfen tarayıcı cache\'ini temizleyip sayfayı yenileyin.';
        } else if (error.message.includes('TESSDATA_PREFIX')) {
          errorMessage = 'Tesseract yapılandırma hatası: Lütfen sayfayı yenileyin.';
        } else {
          errorMessage = `Tesseract başlatılamadı: ${error.message}`;
        }

        setError(errorMessage);
        setWorkerReady(false);
      }
    };

    initWorker();
    return () => {
      cancelled = true;
      if (workerRef.current) {
        workerRef.current.terminate();
        workerRef.current = null;
        setWorkerReady(false);
      }
    };
  }, [assetBase, isDev, orderedImages.length, setError]);

  useEffect(() => {
    setStatus('idle');
    setCurrentIndex(0);
    setPreviewText('');
    setOcrText('');
    clearTranslation();
  }, [clearTranslation, orderedImages, setOcrText]);

  useEffect(() => {
    if (previewRef.current) {
      previewRef.current.scrollTop = previewRef.current.scrollHeight;
    }
  }, [previewText]);
  useEffect(() => {
    if (translationPreviewRef.current) {
      translationPreviewRef.current.scrollTop = translationPreviewRef.current.scrollHeight;
    }
  }, [translatedText]);

  useEffect(() => {
    if (!total || status === 'done' || !workerReady) return;
    abortRef.current = false;
    const run = async () => {
      setStatus('running');
      setCurrentIndex(0);
      const worker = workerRef.current;
      if (!worker) return;
      try {
        let combinedText = '';
        setOcrText('');
        setPreviewText('');
        for (let index = 0; index < orderedImages.length; index += 1) {
          if (abortRef.current) break;
          const image = orderedImages[index];
          setCurrentIndex(index + 1);
          // eslint-disable-next-line no-await-in-loop
          const { data } = await worker.recognize(image.blob);
          const correctedText = correctTurkishCharacters(data.text || '');
          if (correctedText) {
            combinedText = combinedText
              ? `${combinedText}\n\n${correctedText}`
              : correctedText;
            setPreviewText(combinedText);
          }
        }
        if (!abortRef.current) {
          setOcrText(combinedText);
          setStatus('done');
        }
      } catch (error) {
        if (!abortRef.current) {
          setError(error.message);
          setStatus('idle');
        }
      }
    };
    run();
    return () => {
      abortRef.current = true;
    };
  }, [orderedImages, setError, setOcrText, status, total, workerReady]);

  useEffect(() => {
    if (status !== 'done') return;
    if (!ocrText?.trim()) return;
    if (translationStatus === 'running' || translationStatus === 'done') return;

    let cancelled = false;
    const sections = segmentOcrText(ocrText);
    if (!sections.length) return;

    const runTranslation = async () => {
      setTranslationStatus('running');
      setTranslationError(null);
      setTranslationProgress(0);
      setTranslatedText('');
      try {
        const translatedChunks = [];
        for (let index = 0; index < sections.length; index += 1) {
          if (cancelled) return;
          const chunk = sections[index];
          // eslint-disable-next-line no-await-in-loop
          const translated = await translateChunkToTurkish(chunk);
          if (cancelled) return;
          translatedChunks[index] = translated;
          const combined = translatedChunks.filter(Boolean).join('\n\n');
          setTranslatedText(combined);
          setTranslationProgress(Math.round(((index + 1) / sections.length) * 100));
        }
        if (!cancelled) {
          setTranslationStatus('done');
        }
      } catch (error) {
        if (!cancelled) {
          setTranslationStatus('error');
          setTranslationError(error.message || 'Çeviri tamamlanamadı.');
        }
      }
    };

    runTranslation();

    return () => {
      cancelled = true;
    };
  }, [
    ocrText,
    setTranslatedText,
    setTranslationError,
    setTranslationProgress,
    setTranslationStatus,
    status,
    translationTrigger,
  ]);

  if (!orderedImages.length) {
    return (
      <Stack spacing={2}>
        <Alert severity="info">Önce görselleri cropla.</Alert>
        <Button variant="contained" onClick={() => navigate('/bulk-crop')}>
          Toplu Crop adımına dön
        </Button>
      </Stack>
    );
  }

  const progressValue =
    workerReady && total ? (currentIndex / total) * 100 : 0;
  const progressVariant = workerReady ? 'determinate' : 'indeterminate';
  const progressText = !workerReady
    ? 'OCR işçisi hazırlanıyor...'
    : status === 'done'
      ? 'OCR işlemi tamamlandı.'
      : `Şu an ${currentIndex}/${total} resim işleniyor`;

  return (
    <Stack spacing={4}>
      <Box textAlign="center">
        <Typography variant="h5">OCR işlemi</Typography>
        <Typography color="text.secondary">
          Tüm görseller sırayla işleniyor. Bu adım biraz sürebilir.
        </Typography>
      </Box>
      <Box>
        <LinearProgress
          variant={progressVariant}
          value={progressVariant === 'determinate' ? progressValue : undefined}
          sx={{ height: 10, borderRadius: 5 }}
        />
        <Typography mt={2} align="center">
          {progressText}
        </Typography>
      </Box>
      <Stack spacing={1}>
        <Box sx={{ p: 2, borderRadius: 2, bgcolor: 'background.default' }}>
          <Typography variant="subtitle1">Ön izleme</Typography>
          <Box
            ref={previewRef}
            sx={{
              mt: 1,
              maxHeight: '8.5em',
              overflowY: 'auto',
              whiteSpace: 'pre-wrap',
              lineHeight: 1.5,
              fontSize: '0.95rem',
              color: 'text.secondary',
              pr: 1,
            }}
          >
            {previewText || 'Metin bekleniyor'}
          </Box>
        </Box>
        <Box sx={{ p: 2, borderRadius: 2, bgcolor: 'background.default' }}>
          <Stack direction={{ xs: 'column', sm: 'row' }} alignItems="flex-start" justifyContent="space-between">
            <Box>
              <Typography variant="subtitle1">Türkçe çeviriler</Typography>
              <Typography variant="body2" color="text.secondary">
                OCR metni parçalara ayrılıp GLM 4.6 ile çevriliyor.
              </Typography>
            </Box>
            {translationStatus === 'error' && (
              <Button
                size="small"
                variant="outlined"
                onClick={() => {
                  clearTranslation();
                  setTranslationTrigger((prev) => prev + 1);
                }}
              >
                Tekrar dene
              </Button>
            )}
          </Stack>
          {translationStatus === 'running' && (
            <Box mt={2}>
              <LinearProgress
                variant="determinate"
                value={translationProgress}
                sx={{ height: 8, borderRadius: 3 }}
              />
              <Typography mt={1} color="text.secondary" variant="caption">
                %{translationProgress} tamamlandı
              </Typography>
            </Box>
          )}
          {translationStatus === 'done' && translatedText && (
            <Alert severity="success" sx={{ mt: 2 }}>
              Çeviri tamamlandı. EPUB üretiminde Türkçe içerik kullanılacak.
            </Alert>
          )}
          {translationStatus === 'error' && translationError && (
            <Alert severity="error" sx={{ mt: 2 }}>
              {translationError}
            </Alert>
          )}
          <Box
            ref={translationPreviewRef}
            sx={{
              mt: 2,
              maxHeight: '8.5em',
              overflowY: 'auto',
              whiteSpace: 'pre-wrap',
              lineHeight: 1.5,
              fontSize: '0.95rem',
              color: 'text.secondary',
              pr: 1,
              border: '1px solid',
              borderColor: 'divider',
              borderRadius: 1.5,
              p: 1.5,
            }}
          >
            {translatedText || 'Çeviri bekleniyor...'}
          </Box>
        </Box>
      </Stack>
      <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} justifyContent="space-between">
        <Button variant="contained" onClick={() => navigate('/bulk-crop')}>
          Geri dön
        </Button>
        <Button
          variant="contained"
          onClick={() => navigate('/epub')}
          disabled={!hasResults || translationStatus === 'running'}
        >
          EPUB oluştur
        </Button>
      </Stack>
    </Stack>
  );
};

export default OcrStep;

const MAX_CHUNK_LENGTH = 800;

const segmentOcrText = (text) => {
  if (!text) return [];
  const normalized = text.replace(/\r\n/g, '\n');
  const paragraphs = normalized.split(/\n{2,}/).map((part) => part.trim()).filter(Boolean);
  const chunks = [];

  paragraphs.forEach((paragraph) => {
    if (paragraph.length <= MAX_CHUNK_LENGTH) {
      chunks.push(paragraph);
      return;
    }

    let remaining = paragraph;
    while (remaining.length > MAX_CHUNK_LENGTH) {
      let sliceIndex = remaining.lastIndexOf(' ', MAX_CHUNK_LENGTH);
      if (sliceIndex === -1 || sliceIndex < MAX_CHUNK_LENGTH * 0.6) {
        sliceIndex = MAX_CHUNK_LENGTH;
      }
      const chunk = remaining.slice(0, sliceIndex).trim();
      if (chunk) {
        chunks.push(chunk);
      }
      remaining = remaining.slice(sliceIndex).trim();
    }
    if (remaining.length) {
      chunks.push(remaining);
    }
  });

  return chunks;
};
