// Image to Text — browser-side OCR via Tesseract.js (lazy-loaded from CDN on first use).

const TESSERACT_URL = 'https://unpkg.com/tesseract.js@5.1.1/dist/tesseract.min.js';

function ensureTesseract() {
  if (window.Tesseract) return Promise.resolve(window.Tesseract);
  if (window.__tesseractLoading) return window.__tesseractLoading;
  window.__tesseractLoading = new Promise((resolve, reject) => {
    const s = document.createElement('script');
    s.src = TESSERACT_URL;
    s.onload = () => resolve(window.Tesseract);
    s.onerror = () => reject(new Error('Failed to load Tesseract.js'));
    document.head.appendChild(s);
  });
  return window.__tesseractLoading;
}

const LANGUAGES = [
  { code: 'eng', name: 'English' },
  { code: 'tur', name: 'Türkçe' },
  { code: 'deu', name: 'Deutsch' },
  { code: 'fra', name: 'Français' },
  { code: 'spa', name: 'Español' },
  { code: 'ita', name: 'Italiano' },
  { code: 'nld', name: 'Nederlands' },
  { code: 'por', name: 'Português' },
  { code: 'rus', name: 'Русский' },
  { code: 'ara', name: 'العربية' },
  { code: 'chi_sim', name: '中文 (简体)' },
  { code: 'jpn', name: '日本語' },
];

window.TOOL_HANDLERS['image-to-text'] = function ImageToTextTool() {
  const [file, setFile] = React.useState(null);
  const [src, setSrc] = React.useState('');
  const [lang, setLang] = React.useState('eng');
  const [status, setStatus] = React.useState('');
  const [progress, setProgress] = React.useState(0);
  const [text, setText] = React.useState('');
  const [confidence, setConfidence] = React.useState(0);
  const [error, setError] = React.useState('');

  const handleFile = async (f) => {
    if (!f || !f.type.startsWith('image/')) return;
    setFile(f); setSrc(URL.createObjectURL(f));
    setText(''); setConfidence(0); setError('');
    run(f, lang);
  };

  const run = async (f, code) => {
    setError(''); setText(''); setProgress(0);
    try {
      setStatus('Loading engine…');
      const Tesseract = await ensureTesseract();
      setStatus(`Downloading language data (${code})…`);
      const result = await Tesseract.recognize(f, code, {
        logger: (m) => {
          if (m.status) setStatus(m.status);
          if (typeof m.progress === 'number') setProgress(Math.round(m.progress * 100));
        },
      });
      setText((result.data.text || '').trim());
      setConfidence(Math.round(result.data.confidence || 0));
      setStatus('Done');
    } catch (e) {
      setError(e.message || String(e));
      setStatus('');
    }
  };

  const copy = () => navigator.clipboard.writeText(text);
  const downloadTxt = () => {
    const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
    window.downloadBlob(blob, (file?.name || 'extracted').replace(/\.[^.]+$/, '') + '.txt');
  };
  const reset = () => {
    if (src) URL.revokeObjectURL(src);
    setFile(null); setSrc(''); setText(''); setStatus(''); setError(''); setProgress(0);
  };

  if (!file) return (
    <div>
      <window.Dropzone onFile={handleFile} title="Drop an image here" hint="PNG, JPG, WebP — OCR runs locally in your browser" accept="image/*" />
      <div className="cmp-meta" style={{ textAlign: 'center', marginTop: 14 }}>
        First run downloads the engine (~2 MB) and language data. Everything stays on your device.
      </div>
    </div>
  );

  const busy = !text && !error;

  return (
    <div>
      <div className="cmp-preview">
        <div className="cmp-side">
          <div className="cmp-ttl">Image</div>
          <img src={src} alt="" />
          <div className="mini-row" style={{ marginTop: 10 }}>
            <div className="mini-field">
              <label className="mini-label">Language</label>
              <select className="mini-input" value={lang}
                      onChange={(e) => { setLang(e.target.value); run(file, e.target.value); }}
                      disabled={busy}>
                {LANGUAGES.map(l => <option key={l.code} value={l.code}>{l.name}</option>)}
              </select>
            </div>
          </div>
        </div>
        <div className="cmp-side after">
          <div className="cmp-ttl">Extracted text {confidence ? `· ${confidence}% confidence` : ''}</div>
          {busy && !error && (
            <div style={{ padding: 16 }}>
              <div style={{ fontSize: 13, marginBottom: 8 }}>{status || 'Working…'}</div>
              <div className="pw-bar"><div className="pw-fill" style={{ width: progress + '%', background: 'var(--id-brand-blue)' }} /></div>
              <div className="cmp-meta" style={{ marginTop: 8 }}>{progress}%</div>
            </div>
          )}
          {error && (
            <div style={{ padding: 16, color: 'var(--id-danger, #c8321f)' }}>
              Error: {error}
              <div className="cmp-meta" style={{ marginTop: 6 }}>Check your network and try again.</div>
            </div>
          )}
          {!busy && !error && (
            <textarea className="mini-input mini-textarea"
              style={{ minHeight: 200, fontFamily: 'ui-monospace, monospace', fontSize: 13 }}
              value={text} onChange={(e) => setText(e.target.value)} />
          )}
        </div>
      </div>
      <div className="cmp-actions">
        <button className="btn btn-secondary" onClick={reset}><window.Icon name="upload" size={16} /> Another image</button>
        <button className="btn btn-secondary" onClick={copy} disabled={!text}><window.Icon name="doc" size={16} /> Copy text</button>
        <button className="btn btn-primary" onClick={downloadTxt} disabled={!text}><window.Icon name="download" size={16} /> Download .txt</button>
      </div>
    </div>
  );
};
