import React from 'react'
import { sfx } from '../utils/audio'
import CustomModal from './CustomModal'
import { getQuestionsMap, setQuestionsMap } from '../utils/storage'
import { api } from '../api/mock'
import * as pdfjsLib from 'pdfjs-dist'
import mammoth from 'mammoth'

// Import worker using Vite's ?url suffix to handle it correctly
import pdfWorker from 'pdfjs-dist/build/pdf.worker.min.mjs?url'
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorker

// Helper to read PDF
const readPdf = async (file) => {
  const arrayBuffer = await file.arrayBuffer()
  const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise
  let fullText = ''
  for (let i = 1; i <= pdf.numPages; i++) {
    const page = await pdf.getPage(i)
    const textContent = await page.getTextContent()
    const pageText = textContent.items.map(item => item.str).join(' ')
    fullText += `Page ${i}:\n${pageText}\n\n`
  }
  return fullText
}

// Helper to read Word
const readDocx = async (file) => {
  const arrayBuffer = await file.arrayBuffer()
  const result = await mammoth.extractRawText({ arrayBuffer })
  return result.value
}



const getGameConfig = (gameId) => {
  if (!gameId) return { optionCount: 3, levelCount: 3 }
  // Game 7, 8: 2 Options, 5 Levels
  if ([7, 8].includes(gameId)) return { optionCount: 2, levelCount: 5 }
  // Game 4, 5, 6, 9: 4 Options, 5 Levels
  if ([4, 5, 6, 9].includes(gameId)) return { optionCount: 4, levelCount: 5 }
  // Default: 3 Options, 3 Levels
  return { optionCount: 3, levelCount: 3 }
}

const Level = ({ lvl, item, setQ, setOpt, setCorrect, optionCount }) => (
  <div className="border-2 border-onme-softBlue rounded-xl p-3">
    <h4 className="ui font-bold mb-2">Level {lvl}</h4>
    <div className="ui space-y-2">
      <input value={item.q} onChange={e => setQ(lvl, e.target.value)} placeholder={`Pertanyaan Level ${lvl}`} className="w-full border-2 border-onme-softBlue rounded-lg p-2" />
      <div className={`grid grid-cols-${Math.min(optionCount, 3)} gap-2`}>
        {Array.from({ length: optionCount }).map((_, idx) => (
          <input
            key={idx}
            value={item.options[idx] || ''}
            onChange={e => setOpt(lvl, idx, e.target.value)}
            placeholder={`Pilihan ${String.fromCharCode(65 + idx)}`}
            className="border-2 border-onme-softBlue rounded-lg p-2"
          />
        ))}
      </div>
      <select value={item.correct} onChange={e => setCorrect(lvl, e.target.value)} className="w-full border-2 border-onme-softBlue rounded-lg p-2">
        {Array.from({ length: optionCount }).map((_, idx) => (
          <option key={idx} value={idx}>Jawaban Benar: {String.fromCharCode(65 + idx)}</option>
        ))}
      </select>
    </div>
  </div>
)

export default function TeacherUploadModal({ open, onClose }) {
  // Initialize with enough empty slots
  const [data, setData] = React.useState({})

  const [courses, setCourses] = React.useState([])
  const [courseId, setCourseId] = React.useState('')
  const [moduleIndex, setModuleIndex] = React.useState(0)

  // Chat State
  const [chatHistory, setChatHistory] = React.useState([{
    sender: 'ai',
    text: 'Halo Pak/Bu Guru! 👋\nSaya bisa membantu membuat soal pilihan ganda. Ketik topiknya, dan soal akan **otomatis terisi** ke form sebelah kanan!\nContoh: "Buatkan soal matematika tentang penjumlahan"'
  }])
  const [chatInput, setChatInput] = React.useState('')
  const [isTyping, setIsTyping] = React.useState(false)
  const chatEndRef = React.useRef(null)

  // Derived state
  const gameId = React.useMemo(() => deriveGameId(courseId, moduleIndex), [courseId, moduleIndex])
  const { optionCount, levelCount } = getGameConfig(gameId)

  // Scroll to bottom of chat
  React.useEffect(() => {
    chatEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [chatHistory, isTyping])

  // Initialize data structure when levelCount changes
  React.useEffect(() => {
    setData(prev => {
      const next = { ...prev }
      for (let i = 1; i <= levelCount; i++) {
        if (!next[i]) next[i] = { q: '', options: Array(5).fill(''), correct: 0 }
      }
      return next
    })
  }, [levelCount])

  React.useEffect(() => {
    if (open) {
      (async () => {
        try {
          const list = await api.getCourses(); setCourses(list)
          const first = list?.[0]; if (first) { setCourseId(first.id); setModuleIndex(0) }
        } catch { }
        try {
          // Preload from DB for the first selection
          const gid = deriveGameId(courseId, moduleIndex) // Use local var as state might not be ready
          if (gid) {
            const res = await fetch(`http://localhost/landingpage1/lomba/questions.php?game_id=${gid}`)
            if (res.ok) {
              const db = await res.json();
              if (db && Object.keys(db).length) {
                setData(d => {
                  const newData = { ...d }
                  Object.keys(db).forEach(k => {
                    newData[k] = {
                      ...newData[k],
                      ...db[k],
                      options: [...(db[k].options || []), '', '', '', '', ''].slice(0, 5)
                    }
                  })
                  return newData
                })
              }
            }
          } else {
            const map = getQuestionsMap()
            const key = courseId ? `${courseId}:mod:${moduleIndex}` : null
            if (key && map[key]) { setData(map[key]) }
          }
        } catch { }
      })()
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open])

  React.useEffect(() => {
    if (!open || !courseId) return
    try {
      (async () => {
        if (gameId) {
          try {
            const res = await fetch(`http://localhost/landingpage1/lomba/questions.php?game_id=${gameId}`)
            if (res.ok) {
              const db = await res.json();
              if (db && Object.keys(db).length) {
                setData(d => {
                  const newData = {}
                  // Initialize empty structure first
                  for (let i = 1; i <= levelCount; i++) {
                    newData[i] = { q: '', options: Array(5).fill(''), correct: 0 }
                  }

                  Object.keys(db).forEach(k => {
                    newData[k] = {
                      ...newData[k],
                      ...db[k],
                      options: [...(db[k].options || []), '', '', '', '', ''].slice(0, 5)
                    }
                  })
                  return newData
                });
                return
              }
            }
          } catch { }
        }
        const map = getQuestionsMap()
        const key = `${courseId}:mod:${moduleIndex}`
        if (map[key]) setData(map[key])
        else {
          // Reset if no data found
          const newData = {}
          for (let i = 1; i <= levelCount; i++) {
            newData[i] = { q: '', options: Array(5).fill(''), correct: 0 }
          }
          setData(newData)
        }
      })()
    } catch { }
  }, [courseId, moduleIndex, open, gameId, levelCount])

  // AI Logic
  const generateSystemPrompt = () => {
    let prompt = `Kamu adalah asisten guru. Tugasmu membuatkan ${levelCount} Soal Pilihan Ganda (Level 1 sampai ${levelCount}) yang singkat, jelas, dan formatnya mudah dicopy.\n\nFormat yang HARUS kamu gunakan:\n\n`

    for (let i = 1; i <= levelCount; i++) {
      prompt += `**Level ${i}:**\n`
      prompt += `Pertanyaan: [pertanyaan level ${i}]\n`
      for (let j = 0; j < optionCount; j++) {
        prompt += `${String.fromCharCode(65 + j)}. [pilihan ${j + 1}]\n`
      }
      prompt += `Jawaban Benar: [${Array.from({ length: optionCount }, (_, k) => String.fromCharCode(65 + k)).join('/')}]\n\n`
    }

    prompt += `Buat soal yang singkat (max 15 kata per pertanyaan), jelas, dan sesuai topik.`
    return prompt
  }

  const parseAIResponse = (text) => {
    try {
      const levels = text.split(/\*\*Level\s*(\d+):\*\*/i);
      let parsed = {};

      for (let i = 1; i < levels.length; i += 2) {
        const levelNum = parseInt(levels[i]);
        const content = levels[i + 1] || '';

        const qMatch = content.match(/Pertanyaan:\s*(.+?)(?=\n|A\.|$)/i);
        const question = qMatch ? qMatch[1].trim() : '';

        const options = []
        for (let j = 0; j < optionCount; j++) {
          const char = String.fromCharCode(65 + j)
          const nextChar = String.fromCharCode(65 + j + 1)
          // Regex to find option text between "A." and "B." (or end of line/next option)
          const regex = new RegExp(`${char}\\.\\s*(.+?)(?=\\n|${nextChar}\\.|Jawaban|$)`, 'i')
          const match = content.match(regex)
          options.push(match ? match[1].trim() : '')
        }

        const correctMatch = content.match(/Jawaban\s*Benar:\s*([A-E])/i);
        let correct = 0;
        if (correctMatch) {
          const letter = correctMatch[1].toUpperCase();
          correct = letter.charCodeAt(0) - 65;
        }

        if (levelNum >= 1 && levelNum <= levelCount && question) {
          // Pad options to 5 for compatibility
          const paddedOptions = [...options, ...Array(5).fill('')].slice(0, 5)
          parsed[levelNum] = { q: question, options: paddedOptions, correct: correct };
        }
      }
      return parsed;
    } catch (e) {
      console.error('Parse error:', e);
      return null;
    }
  }

  const sendMessage = async () => {
    const text = chatInput.trim();
    if (!text) return;

    setChatHistory(prev => [...prev, { sender: 'user', text }])
    setChatInput('')
    setIsTyping(true)

    try {
      const response = await fetch('http://localhost/landingpage1/lomba/api.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          message: text,
          system_prompt: generateSystemPrompt(),
          max_tokens: 1024,
          temperature: 0.7
        })
      });
      const data = await response.json();
      setIsTyping(false)

      if (data.choices && data.choices[0] && data.choices[0].message) {
        const aiResponse = data.choices[0].message.content;
        setChatHistory(prev => [...prev, { sender: 'ai', text: aiResponse }])

        // Auto-fill forms
        const parsed = parseAIResponse(aiResponse);
        if (parsed && Object.keys(parsed).length > 0) {
          setData(prev => {
            const next = { ...prev }
            Object.keys(parsed).forEach(lvl => {
              if (next[lvl]) {
                next[lvl] = { ...next[lvl], ...parsed[lvl] }
              }
            })
            return next
          })
          setChatHistory(prev => [...prev, { sender: 'ai', text: '✅ Soal berhasil diisi otomatis ke form! Cek dan edit jika perlu, lalu klik SIMPAN.' }])
          sfx.play('success')
        }
      } else {
        setChatHistory(prev => [...prev, { sender: 'ai', text: '❌ Maaf, terjadi kesalahan pada AI.' }])
      }
    } catch (error) {
      setIsTyping(false)
      setChatHistory(prev => [...prev, { sender: 'ai', text: '❌ Gagal menghubungi AI: ' + error.message }])
    }
  }

  const [modal, setModal] = React.useState({ open: false, title: '', msg: '', type: 'alert', onConfirm: null })

  const showModal = (msg, title = 'Info') => {
    setModal({ open: true, title, msg, type: 'alert', onConfirm: () => setModal(m => ({ ...m, open: false })) })
  }

  if (!open) return null

  const save = () => {
    for (let lvl = 1; lvl <= levelCount; lvl++) {
      const it = data[lvl]
      if (!it) continue;
      // Validate only the required number of options
      const requiredOptions = it.options.slice(0, optionCount)
      if (!it.q || requiredOptions.some(o => !o)) {
        showModal(`Lengkapi Level ${lvl} terlebih dahulu (Isi ${optionCount} pilihan)`, 'Validasi')
        return
      }
    }
    if (!courseId) { showModal('Pilih course terlebih dahulu', 'Validasi'); return }
    if (!gameId) { showModal('Mapping game_id tidak ditemukan', 'Error'); return }
    ; (async () => {
      try {
        // Clean up data before sending: remove unused options
        const cleanData = {}
        for (let lvl = 1; lvl <= levelCount; lvl++) {
          if (data[lvl]) {
            cleanData[lvl] = {
              ...data[lvl],
              options: data[lvl].options.slice(0, optionCount)
            }
          }
        }

        const resp = await fetch('http://localhost/landingpage1/lomba/questions.php', {
          method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ game_id: gameId, data: cleanData })
        })
        if (!resp.ok) { throw new Error('Gagal simpan ke DB') }
        // Simpan cache lokal opsional
        const key = `${courseId}:mod:${moduleIndex}`
        const map = { ...getQuestionsMap(), [key]: cleanData }
        setQuestionsMap(map)
        sfx.play('success')
        showModal('✅ Materi tersimpan di database untuk game ' + gameId, 'Berhasil')
        // Delay closing to let user see success message
        setTimeout(() => onClose(true), 1500)
      } catch (e) { showModal('Gagal menyimpan: ' + e.message, 'Error') }
    })()
  }

  function deriveGameId(cid, modIdx) {
    // Seed mapping: c1 Matematika -> 1..3, c3 Inggris -> 4..6, c2 Indonesia -> 7..9
    if (!cid) return null
    const byId = { c1: 1, c3: 4, c2: 7 }
    const start = byId[cid]
    if (!start && start !== 0) return null
    return start + Number(modIdx || 0)
  }

  const setQ = (lvl, val) => setData(prev => ({ ...prev, [lvl]: { ...prev[lvl], q: val } }))
  const setOpt = (lvl, idx, val) => setData(prev => ({ ...prev, [lvl]: { ...prev[lvl], options: prev[lvl].options.map((o, i) => i === idx ? val : o) } }))
  const setCorrect = (lvl, val) => setData(prev => ({ ...prev, [lvl]: { ...prev[lvl], correct: Number(val) } }))

  const handleFileUpload = async (e) => {
    const file = e.target.files[0]
    if (!file) return

    setIsTyping(true) // Show loading state immediately
    setChatHistory(prev => [...prev, { sender: 'user', text: `📂 Mengupload dan memproses file: ${file.name}...` }])

    try {
      let content = ''
      if (file.type === 'application/pdf') {
        content = await readPdf(file)
      } else if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
        content = await readDocx(file)
      } else {
        // Text files
        content = await new Promise((resolve) => {
          const reader = new FileReader()
          reader.onload = (ev) => resolve(ev.target.result)
          reader.readAsText(file)
        })
      }

      const message = `📂 File terupload: ${file.name}\n\nTolong buatkan soal berdasarkan materi di atas.`

      // Update history with success message
      setChatHistory(prev => {
        const newHist = [...prev]
        newHist.pop() // Remove "Processing..." message
        newHist.push({ sender: 'user', text: message })
        return newHist
      })

      // Send to AI
      const fullPrompt = `Berikut adalah materi dari file ${file.name}:\n\n${content}\n\n${message}`

      const response = await fetch('http://localhost/landingpage1/lomba/api.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          message: fullPrompt,
          system_prompt: generateSystemPrompt(),
          max_tokens: 2048,
          temperature: 0.7
        })
      });
      const data = await response.json();
      setIsTyping(false)

      if (data.choices && data.choices[0] && data.choices[0].message) {
        const aiResponse = data.choices[0].message.content;
        setChatHistory(prev => [...prev, { sender: 'ai', text: aiResponse }])

        const parsed = parseAIResponse(aiResponse);
        if (parsed && Object.keys(parsed).length > 0) {
          setData(prev => {
            const next = { ...prev }
            Object.keys(parsed).forEach(lvl => {
              if (next[lvl]) {
                next[lvl] = { ...next[lvl], ...parsed[lvl] }
              }
            })
            return next
          })
          setChatHistory(prev => [...prev, { sender: 'ai', text: '✅ Soal berhasil diisi otomatis dari file!' }])
          sfx.play('success')
        }
      } else {
        setChatHistory(prev => [...prev, { sender: 'ai', text: '❌ Maaf, terjadi kesalahan pada AI.' }])
      }

    } catch (error) {
      setIsTyping(false)
      console.error(error)
      setChatHistory(prev => [...prev, { sender: 'ai', text: '❌ Gagal memproses file: ' + error.message }])
    }

    // Reset input
    e.target.value = ''
  }

  return (
    <div role="dialog" aria-modal="true" className="fixed inset-0 bg-black/40 grid place-items-center p-4 z-50">
      <CustomModal
        isOpen={modal.open}
        title={modal.title}
        message={modal.msg}
        type={modal.type}
        onConfirm={modal.onConfirm}
        onCancel={() => setModal(m => ({ ...m, open: false }))}
      />
      <div className="bg-white rounded-2xl border-4 border-onme-blue max-w-6xl w-full p-4 flex flex-col max-h-[90vh]">
        <h3 className="heading text-onme-blue text-xl mb-3 flex-shrink-0">Upload Materi (Guru)</h3>

        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden">
          {/* Left Column: AI Chat */}
          <div className="flex flex-col bg-slate-50 rounded-xl border-2 border-slate-200 overflow-hidden">
            <div className="p-3 border-b border-slate-200 bg-slate-100">
              <h4 className="font-bold text-slate-700 flex items-center gap-2">
                <span>🤖</span> Asisten Pembuat Soal
              </h4>
              <p className="text-xs text-slate-500">Ketik topik, AI akan mengisi form secara otomatis.</p>
            </div>
            <div className="flex-1 overflow-y-auto p-4 space-y-4 bg-slate-50">
              {chatHistory.map((msg, i) => (
                <div key={i} className={`flex items-start gap-2 ${msg.sender === 'user' ? 'flex-row-reverse' : ''}`}>
                  <div className={`w-8 h-8 rounded-full flex items-center justify-center text-sm flex-shrink-0 ${msg.sender === 'user' ? 'bg-blue-500 text-white' : 'bg-indigo-600 text-white'}`}>
                    {msg.sender === 'user' ? '👤' : '🤖'}
                  </div>
                  <div className={`p-3 rounded-2xl max-w-[85%] text-sm whitespace-pre-wrap ${msg.sender === 'user' ? 'bg-blue-100 text-blue-900 rounded-tr-none' : 'bg-white border border-slate-200 text-slate-800 rounded-tl-none shadow-sm'}`}>
                    {msg.text.replace(/\*\*(.*?)\*\*/g, '$1')}
                  </div>
                </div>
              ))}
              {isTyping && (
                <div className="flex items-start gap-2">
                  <div className="w-8 h-8 rounded-full bg-indigo-600 text-white flex items-center justify-center text-sm flex-shrink-0">🤖</div>
                  <div className="bg-white border border-slate-200 p-3 rounded-2xl rounded-tl-none shadow-sm">
                    <div className="flex gap-1">
                      <span className="w-2 h-2 bg-indigo-400 rounded-full animate-bounce"></span>
                      <span className="w-2 h-2 bg-indigo-400 rounded-full animate-bounce delay-75"></span>
                      <span className="w-2 h-2 bg-indigo-400 rounded-full animate-bounce delay-150"></span>
                    </div>
                  </div>
                </div>
              )}
              <div ref={chatEndRef} />
            </div>
            <div className="p-3 border-t border-slate-200 bg-white">
              <div className="flex gap-2 items-center">
                <label className="cursor-pointer p-2 hover:bg-slate-100 rounded-lg text-slate-500 transition-colors" title="Upload File Materi (.txt, .pdf, .docx)">
                  <input type="file" accept=".txt,.md,.csv,.pdf,.docx" className="hidden" onChange={handleFileUpload} />
                  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
                    <path strokeLinecap="round" strokeLinejoin="round" d="M18.375 12.739l-7.693 7.693a4.5 4.5 0 01-6.364-6.364l10.94-10.94A3 3 0 1119.5 6.182l-7.494 7.494 1.318 1.318 7.494-7.494a4.875 4.875 0 00-6.894-6.894L2.121 10.364" />
                  </svg>
                </label>
                <input
                  value={chatInput}
                  onChange={e => setChatInput(e.target.value)}
                  onKeyPress={e => e.key === 'Enter' && sendMessage()}
                  placeholder="Ketik topik atau upload file..."
                  className="flex-1 border-2 border-slate-200 rounded-lg px-3 py-2 text-sm focus:border-indigo-500 outline-none"
                />
                <button onClick={sendMessage} disabled={isTyping} className="bg-indigo-600 text-white px-4 py-2 rounded-lg font-bold text-sm hover:bg-indigo-700 disabled:opacity-50">
                  Kirim
                </button>
              </div>
            </div>
          </div>

          {/* Right Column: Form */}
          <div className="flex flex-col h-full overflow-hidden">
            <div className="ui grid md:grid-cols-2 gap-3 mb-3 flex-shrink-0">
              <label className="block">
                <span className="font-semibold">Course</span>
                <select value={courseId} onChange={e => setCourseId(e.target.value)} className="w-full border-2 border-onme-softBlue rounded-lg p-2 mt-1">
                  {courses.map(c => <option key={c.id} value={c.id}>{c.title}</option>)}
                </select>
              </label>
              <label className="block">
                <span className="font-semibold">Bab</span>
                <select value={moduleIndex} onChange={e => setModuleIndex(Number(e.target.value))} className="w-full border-2 border-onme-softBlue rounded-lg p-2 mt-1">
                  {(courses.find(c => c.id === courseId)?.modules || []).map((m, i) => <option key={i} value={i}>{m.title}</option>)}
                </select>
              </label>
            </div>

            <div className="space-y-3 overflow-y-auto pr-2 flex-grow">
              {Array.from({ length: levelCount }).map((_, i) => {
                const lvl = i + 1;
                return data[lvl] ? (
                  <Level key={lvl} lvl={lvl} item={data[lvl]} setQ={setQ} setOpt={setOpt} setCorrect={setCorrect} optionCount={optionCount} />
                ) : null
              })}
            </div>

            <div className="flex justify-end gap-2 mt-4 flex-shrink-0">
              <button onClick={save} className="ui rounded-full bg-onme-lime font-bold px-4 py-2">Simpan ke Game</button>
              <button onClick={() => { sfx.play('click'); onClose(false) }} className="ui rounded-full bg-white border-2 border-onme-softBlue px-4 py-2">Batal</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}
