import { useState, useRef } from 'preact/hooks';
import { MindforgeApiService, type FlashcardMode } from '../services/MindforgeApiService';

// Mapping of flashcard mode to its maximum allowed amount
const modeMax: Record<FlashcardMode, number> = {
  Basic: 25,
  Simple: 30,
  Detailed: 70,
  Hyper: 130,
};

import { Button } from './Button';
import './FlashcardComponent.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);
}

export function FlashcardComponent() {
  const [text, setText] = useState('');
  const [fileName, setFileName] = useState('manual_input.md');
  const [amount, setAmount] = useState<number>(20);
  const [mode, setMode] = useState<FlashcardMode>('Simple');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<boolean>(false);

  const handleModeChange = (newMode: FlashcardMode) => {
    setMode(newMode); // set the mode
    setAmount(20); // set the default amount
  };

  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 handleGenerate = async () => {
    if (!text.trim()) {
      setError('Por favor, insira algum texto ou faça upload de um arquivo para gerar os flashcards.');
      return;
    }

    setLoading(true);
    setError(null);
    setSuccess(false);

    try {
      const base64Content = utf8ToBase64(text);
      const res = await MindforgeApiService.generateFlashcards({
        fileContent: base64Content,
        fileName,
        amount,
        mode
      });

      const csvContent = res.result;
      downloadCSV(csvContent);
      setSuccess(true);
    } catch (err: any) {
      setError(err.message || 'Ocorreu um erro ao gerar os flashcards.');
    } finally {
      setLoading(false);
    }
  };

  const downloadCSV = (content: string) => {
    // Adicionar BOM do UTF-8 para o Excel reconhecer os caracteres corretamente
    const bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
    const blob = new Blob([bom, content], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', `flashcards_${Date.now()}.csv`);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  };

  return (
    <div className="flashcard-container">
      <h2 className="title" style={{ fontSize: '2.5rem' }}>Gerador de Flashcards</h2>
      <p className="subtitle">Crie flashcards baseados nos seus materiais de estudo rapidamente.</p>

      <div className="flashcard-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 de estudo aqui ou faça upload do material..."
          />
        </div>

        <div className="file-input-wrapper">
          <input
            type="file"
            accept=".md,.txt,.html"
            ref={fileInputRef}
            onChange={handleFileUpload}
            className="file-input"
            id="flashcard-file"
          />
          <label htmlFor="flashcard-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>Quantidade Estimada de Flashcards (10 - 100)</label>
          <div className="slider-wrapper">
            <input
              type="range"
              className="slider-input"
              min="10"
              max={modeMax[mode]}
              value={amount}
              onInput={(e) => setAmount(parseInt((e.target as HTMLInputElement).value))}
            />
            <span className="amount-display">{amount}</span>
          </div>
        </div>

        <div className="input-group">
          <label>Modo de Geração</label>
          <div className="radio-group">
            <div className="radio-item">
              <input
                type="radio"
                id="mode-basic"
                name="mode"
                value="Basic"
                checked={mode === 'Basic'}
                onChange={(e) => handleModeChange((e.target as HTMLInputElement).value as FlashcardMode)}
              />
              <label htmlFor="mode-basic" className="radio-label" title="Modo básico, rápido e simples. Geralmente conteúdos simples e repetíveis">Básico</label>
            </div>
            <div className="radio-item">
              <input
                type="radio"
                id="mode-simple"
                name="mode"
                value="Simple"
                checked={mode === 'Simple'}
                onChange={(e) => handleModeChange((e.target as HTMLInputElement).value as FlashcardMode)}
              />
              <label htmlFor="mode-simple" className="radio-label" title="Modo rápido e simples, possui uma melhor compreensão">Simples</label>
            </div>
            <div className="radio-item">
              <input
                type="radio"
                id="mode-detailed"
                name="mode"
                value="Detailed"
                checked={mode === 'Detailed'}
                onChange={(e) => handleModeChange((e.target as HTMLInputElement).value as FlashcardMode)}
              />
              <label htmlFor="mode-detailed" className="radio-label" title="Modelo avançado, maior gama de detalhes">Detalhado</label>
            </div>
            <div className="radio-item">
              <input
                type="radio"
                id="mode-hyper"
                name="mode"
                value="Hyper"
                checked={mode === 'Hyper'}
                onChange={(e) => handleModeChange((e.target as HTMLInputElement).value as FlashcardMode)}
              />
              <label htmlFor="mode-hyper" className="radio-label" title="Modelo Pro, complexo e com perguntas adicionais">Hiper</label>
            </div>
          </div>
        </div>

        <Button variant="primary" onClick={handleGenerate} disabled={loading} style={{ marginTop: '1rem' }}>
          {loading ? 'Gerando...' : 'Gerar Flashcards e Baixar (CSV)'}
        </Button>

        {error && <div style={{ color: '#ff7b72', marginTop: '1rem' }}>{error}</div>}
        {success && <div className="success-message">Flashcards gerados com sucesso! O download deve ter começado.</div>}
      </div>

      {loading && (
        <div className="spinner-container">
          <div className="spinner"></div>
          <p>Extraindo os melhores conceitos para os seus flashcards. Aguarde...</p>
        </div>
      )}
    </div>
  );
}
