import { useState, useRef } from 'preact/hooks';
import { MindforgeApiService } from '../services/MindforgeApiService';
import { Button } from './Button';
import * as diff from 'diff';
import { marked } from 'marked';
import './VerificadorComponent.css';

function utf8ToBase64(str: string): string {
  const bytes = new TextEncoder().encode(str);
  const binary = Array.from(bytes, byte => String.fromCharCode(byte)).join('');
  return window.btoa(binary);
}

type CheckTypeEnum = 'language' | 'content' | 'both';

export function VerificadorComponent() {
  const [text, setText] = useState('');
  const [fileName, setFileName] = useState('manual_input.md');
  const [checkType, setCheckType] = useState<CheckTypeEnum>('language');

  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const [languageResult, setLanguageResult] = useState<string | null>(null);
  const [contentResult, setContentResult] = useState<string | null>(null);

  const fileInputRef = useRef<HTMLInputElement>(null);

  const handleFileUpload = (e: Event) => {
    const target = e.target as HTMLInputElement;
    if (target.files && target.files.length > 0) {
      const file = target.files[0];
      setFileName(file.name);
      const reader = new FileReader();
      reader.onload = (event) => {
        if (event.target?.result) {
          setText(event.target.result as string);
        }
      };
      reader.readAsText(file);
    }
  };

  const handleSubmit = async () => {
    if (!text.trim()) {
      setError('Por favor, insira algum texto ou faça upload de um arquivo.');
      return;
    }

    setLoading(true);
    setError(null);
    setLanguageResult(null);
    setContentResult(null);

    const base64Content = utf8ToBase64(text);

    try {
      if (checkType === 'both') {
        const [langRes, contRes] = await Promise.all([
          MindforgeApiService.checkFile({ fileContent: base64Content, fileName, checkType: 'language' }),
          MindforgeApiService.checkFile({ fileContent: base64Content, fileName, checkType: 'content' })
        ]);
        setLanguageResult(langRes.result);
        setContentResult(contRes.result);
      } else {
        const res = await MindforgeApiService.checkFile({ fileContent: base64Content, fileName, checkType });
        if (checkType === 'language') setLanguageResult(res.result);
        else setContentResult(res.result);
      }
    } catch (err: any) {
      setError(err.message || 'Ocorreu um erro ao processar sua requisição.');
    } finally {
      setLoading(false);
    }
  };

  const renderDiff = (original: string, updated: string) => {
    const diffResult = diff.diffWordsWithSpace(original, updated);
    return (
      <div className="diff-view">
        {diffResult.map((part, index) => {
          const className = part.added ? 'diff-added' : part.removed ? 'diff-removed' : '';
          return (
            <span key={index} className={className}>
              {part.value}
            </span>
          );
        })}
      </div>
    );
  };

  return (
    <div className="verificador-container">
      <h2 className="title" style={{ fontSize: '2.5rem' }}>Verificador de Arquivos</h2>
      <p className="subtitle">Faça o upload do seu arquivo Markdown para validação de linguagem ou conteúdo.</p>

      <div className="verificador-form">
        <div className="input-group">
          <label>Texto (Markdown)</label>
          <textarea
            className="text-area"
            value={text}
            onInput={(e) => setText((e.target as HTMLTextAreaElement).value)}
            placeholder="Cole seu texto aqui ou faça upload de um arquivo..."
          />
        </div>

        <div className="file-input-wrapper">
          <input
            type="file"
            accept=".md,.txt"
            ref={fileInputRef}
            onChange={handleFileUpload}
            className="file-input"
            id="verificador-file"
          />
          <label htmlFor="verificador-file" className="file-input-label">
            📁 Escolher Arquivo
          </label>
          <span style={{ fontSize: '0.9rem', color: 'rgba(255,255,255,0.6)' }}>
            {fileName !== 'manual_input.md' ? fileName : 'Nenhum arquivo selecionado'}
          </span>
        </div>

        <div className="input-group">
          <label>Tipo de Verificação</label>
          <select
            className="select-input"
            value={checkType}
            onChange={(e) => setCheckType((e.target as HTMLSelectElement).value as CheckTypeEnum)}
          >
            <option value="language">Linguagem</option>
            <option value="content">Conteúdo</option>
            <option value="both">Linguagem e Conteúdo</option>
          </select>
        </div>

        <Button variant="primary" onClick={handleSubmit} disabled={loading} style={{ marginTop: '1rem' }}>
          {loading ? 'Processando...' : 'Verificar'}
        </Button>

        {error && <div style={{ color: '#ff7b72', marginTop: '1rem' }}>{error}</div>}
      </div>

      {loading && (
        <div className="spinner-container">
          <div className="spinner"></div>
          <p>Analisando sua forja mental...</p>
        </div>
      )}

      {/* Render Results */}
      {!loading && (languageResult || contentResult) && (
        <div className="response-section">
          {checkType === 'language' && languageResult && (
            <div className="side-pane">
              <div className="pane-title">Resultado - Linguagem (Diff)</div>
              <div className="response-content">
                {renderDiff(text, languageResult)}
              </div>
            </div>
          )}

          {checkType === 'content' && contentResult && (
            <div className="side-pane">
              <div className="pane-title">Resultado - Conteúdo</div>
              <div 
                className="response-content markdown-body" 
                dangerouslySetInnerHTML={{ __html: marked.parse(contentResult) as string }} 
              />
            </div>
          )}

          {checkType === 'both' && languageResult && contentResult && (
            <div className="side-by-side">
              <div className="side-pane">
                <div className="pane-title">Linguagem (Diff)</div>
                <div className="response-content" style={{ minHeight: '300px' }}>
                  {renderDiff(text, languageResult)}
                </div>
              </div>
              <div className="side-pane">
                <div className="pane-title">Conteúdo</div>
                <div 
                  className="response-content markdown-body" 
                  style={{ minHeight: '300px' }}
                  dangerouslySetInnerHTML={{ __html: marked.parse(contentResult) as string }} 
                />
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}
