import { useState, useEffect, useRef } from "react"
import api from "../lib/api"
import Reveal from "./Reveal"

const API_URL = import.meta.env.VITE_API_URL || "http://localhost:8000"
const G = "linear-gradient(135deg, #1d4ed8 0%, #0891b2 100%)"

const PREPARE_STEPS = [
  { key: "transcribing", label: "Transcribing audio" },
  { key: "diarizing", label: "Identifying speakers" },
  { key: "detecting", label: "Detecting your voice" },
]

const FINALIZE_STEPS = [
  { key: "extracting", label: "Extracting behavioral signals" },
  { key: "scoring", label: "Scoring dimensions" },
  { key: "generating", label: "Generating AI insights" },
]

function StepProgress({ steps, currentStep, title, onCancel }) {
  const currentIdx = steps.findIndex(s => s.key === currentStep)

  return (
    <div style={{ textAlign: "center", padding: "56px 0" }}>
      <p style={{ fontWeight: 700, fontSize: 17, margin: "0 0 6px", color: "#f0eeff" }}>
        {title}
      </p>
      <p style={{ fontSize: 13, color: "#4a4865", margin: "0 0 44px" }}>
        This usually takes 1–3 minutes
      </p>
      <div style={{ display: "flex", flexDirection: "column", gap: 22,
        maxWidth: 300, margin: "0 auto", textAlign: "left" }}>
        {steps.map((step, idx) => {
          const isDone = currentIdx > idx
          const isCurrent = currentIdx === idx
          return (
            <div key={step.key} style={{ display: "flex", alignItems: "center", gap: 14 }}>
              <div style={{
                width: 28, height: 28, borderRadius: "50%", flexShrink: 0,
                background: isDone ? G : isCurrent ? "rgba(29,78,216,0.1)" : "#151922",
                border: `2px solid ${isDone ? "transparent" : isCurrent ? "#1d4ed8" : "#1e2438"}`,
                display: "flex", alignItems: "center", justifyContent: "center",
                boxShadow: isCurrent ? "0 0 16px rgba(29,78,216,0.4)" : "none",
                transition: "all 0.3s",
              }}>
                {isDone && <span style={{ color: "white", fontSize: 12, fontWeight: 700 }}>✓</span>}
                {isCurrent && <div style={{ width: 8, height: 8, background: "#1d4ed8",
                  borderRadius: "50%" }} />}
              </div>
              <div>
                <span style={{
                  fontSize: 14,
                  color: isDone ? "#4a4865" : isCurrent ? "#f0eeff" : "#2a2a42",
                  fontWeight: isCurrent ? 600 : 400,
                }}>
                  {step.label}
                </span>
                {isCurrent && (
                  <span style={{ fontSize: 12, color: "#5b9cf6", marginLeft: 6 }}>
                    — in progress…
                  </span>
                )}
              </div>
            </div>
          )
        })}
      </div>
      <p style={{ fontSize: 12, color: "#4a4865", marginTop: 40 }}>
        You can browse History while this runs
      </p>
      {onCancel && (
        <button onClick={onCancel}
          style={{ marginTop: 12, background: "none", border: "1px solid #1e2438",
            borderRadius: 6, padding: "6px 18px", fontSize: 12, color: "#4a4865",
            cursor: "pointer" }}>
          Cancel
        </button>
      )}
    </div>
  )
}

export default function UploadView({ onResults, onActivate }) {
  const [file, setFile] = useState(null)
  const [step, setStep] = useState("idle")
  const [error, setError] = useState("")
  const [progressStep, setProgressStep] = useState(null)
  const [serverWarm, setServerWarm] = useState(true)
  const [usage, setUsage] = useState(null)

  useEffect(() => {
    api.get("/api/usage").then(r => setUsage(r.data)).catch(() => {})
  }, [])

  const esRef = useRef(null)
  const pollRef = useRef(null)
  const finalizeStartedRef = useRef(false)

  const handleFinalize = async (sessionId, confirmedSpeaker) => {
    setStep("finalizing")
    setError("")
    setProgressStep(null)
    onActivate?.()

    try {
      const form = new FormData()
      form.append("session_id", sessionId)
      form.append("confirmed_speaker", confirmedSpeaker)

      const { data: { job_id } } = await api.post(
        "/api/finalize/start", form,
        { headers: { "Content-Type": "multipart/form-data" } }
      )

      const es = new EventSource(`${API_URL}/api/finalize/${job_id}/stream`)
      esRef.current = es

      es.onmessage = (e) => {
        const msg = JSON.parse(e.data)
        if (msg.event === "progress") {
          setProgressStep(msg.step)
        } else if (msg.event === "done") {
          es.close(); esRef.current = null
          sessionStorage.removeItem("pending_finalize_session")
          setStep("idle"); setFile(null)
          api.get("/api/usage").then(r => setUsage(r.data)).catch(() => {})
          onResults(msg.data)
        } else if (msg.event === "error") {
          es.close(); esRef.current = null
          sessionStorage.removeItem("pending_finalize_session")
          setError(msg.message || "Analysis failed."); setStep("idle")
        }
      }

      es.onerror = async () => {
        es.close(); esRef.current = null
        try {
          await new Promise(r => setTimeout(r, 1200))
          const res = await api.get("/api/sessions")
          const saved = res.data.find(s => s.session_id === sessionId)
          if (saved) {
            sessionStorage.removeItem("pending_finalize_session")
            setStep("idle"); setFile(null)
            onResults({
              signals: saved.signals, insights: saved.insights,
              dimensions: saved.dimensions || {}, filename: saved.filename,
              detected_speaker: saved.detected_speaker,
              speaker_confirmed: saved.speaker_confirmed,
              session_id: saved.session_id,
              available_speakers: saved.available_speakers || [],
            })
            return
          }
        } catch {}
        sessionStorage.removeItem("pending_finalize_session")
        setError("Connection lost during analysis. Please try again.")
        setStep("idle")
      }
    } catch (e) {
      sessionStorage.removeItem("pending_finalize_session")
      setError(e.response?.data?.detail || "Analysis failed.")
      setStep("idle")
    }
  }

  const cancelRecovery = () => {
    clearInterval(pollRef.current); pollRef.current = null
    esRef.current?.close(); esRef.current = null
    sessionStorage.removeItem("pending_prepare_job")
    sessionStorage.removeItem("pending_finalize_session")
    setStep("idle")
  }

  useEffect(() => {
    const savedFinalize = sessionStorage.getItem("pending_finalize_session")
    if (savedFinalize) {
      const { session_id, detected_speaker } = JSON.parse(savedFinalize)
      setStep("finalizing"); onActivate?.()
      handleFinalize(session_id, detected_speaker)
      return
    }
    const saved = sessionStorage.getItem("pending_prepare_job")
    if (!saved) return
    const { job_id } = JSON.parse(saved)
    setStep("preparing"); onActivate?.()
    api.get(`/api/prepare/${job_id}/status`)
      .then(res => {
        sessionStorage.removeItem("pending_prepare_job")
        handleFinalize(res.data.session_id, res.data.detected_speaker || "SPEAKER_00")
      })
      .catch(() => {
        clearInterval(pollRef.current)
        pollRef.current = setInterval(async () => {
          try {
            const res = await api.get(`/api/prepare/${job_id}/status`)
            clearInterval(pollRef.current); pollRef.current = null
            sessionStorage.removeItem("pending_prepare_job")
            handleFinalize(res.data.session_id, res.data.detected_speaker || "SPEAKER_00")
          } catch (e) {
            if (e.response?.status && e.response.status !== 404) cancelRecovery()
          }
        }, 10000)
      })
  }, [])

  useEffect(() => {
    return () => { esRef.current?.close(); clearInterval(pollRef.current) }
  }, [])

  // Cold-start warmup check — HF Spaces sleeps after inactivity
  useEffect(() => {
    let cancelled = false
    const timer = setTimeout(() => {
      if (!cancelled) setServerWarm(false)
    }, 3500)
    api.get("/health").then(() => {
      clearTimeout(timer)
      if (!cancelled) setServerWarm(true)
    }).catch(() => {
      clearTimeout(timer)
      if (!cancelled) setServerWarm(false)
    })
    return () => { cancelled = true; clearTimeout(timer) }
  }, [])

  const handlePrepare = async () => {
    if (!file) return
    setStep("preparing"); setError(""); setProgressStep(null)
    finalizeStartedRef.current = false

    try {
      const form = new FormData()
      form.append("audio", file)
      form.append("filename", file.name)

      const { data: { job_id } } = await api.post(
        "/api/prepare/start", form,
        { headers: { "Content-Type": "multipart/form-data" } }
      )

      sessionStorage.setItem("pending_prepare_job", JSON.stringify({ job_id }))

      const handlePrepareDone = (data) => {
        if (finalizeStartedRef.current) return
        finalizeStartedRef.current = true
        clearInterval(pollRef.current); pollRef.current = null
        sessionStorage.removeItem("pending_prepare_job")
        sessionStorage.setItem("pending_finalize_session", JSON.stringify({
          session_id: data.session_id,
          detected_speaker: data.detected_speaker || "SPEAKER_00",
        }))
        handleFinalize(data.session_id, data.detected_speaker || "SPEAKER_00")
      }

      const startPolling = () => {
        clearInterval(pollRef.current)
        pollRef.current = setInterval(async () => {
          try {
            const res = await api.get(`/api/prepare/${job_id}/status`)
            if (res.data.current_step) setProgressStep(res.data.current_step)
            handlePrepareDone(res.data)
          } catch (e) {
            if (e.response?.status && e.response.status !== 404) {
              clearInterval(pollRef.current); pollRef.current = null
              setError("Something went wrong. Please try again."); setStep("idle")
            }
          }
        }, 10000)
      }

      const es = new EventSource(`${API_URL}/api/prepare/${job_id}/stream`)
      esRef.current = es

      es.onmessage = (e) => {
        const msg = JSON.parse(e.data)
        if (msg.event === "progress") setProgressStep(msg.step)
        else if (msg.event === "done") { es.close(); esRef.current = null; handlePrepareDone(msg.data) }
        else if (msg.event === "error") {
          es.close(); esRef.current = null
          sessionStorage.removeItem("pending_prepare_job")
          setError(msg.message || "Preparation failed."); setStep("idle")
        }
      }

      es.onerror = async () => {
        es.close(); esRef.current = null
        await new Promise(r => setTimeout(r, 1500))
        try {
          const res = await api.get(`/api/prepare/${job_id}/status`)
          if (res.data.current_step) setProgressStep(res.data.current_step)
          handlePrepareDone(res.data); return
        } catch {}
        startPolling()
      }

    } catch (e) {
      setError(e.response?.data?.detail || "Preparation failed."); setStep("idle")
    }
  }

  if (step === "preparing") return (
    <StepProgress steps={PREPARE_STEPS} currentStep={progressStep || "transcribing"}
      title="Analyzing your conversation…" onCancel={cancelRecovery} />
  )

  if (step === "finalizing") return (
    <StepProgress steps={FINALIZE_STEPS} currentStep={progressStep || "extracting"}
      title="Building your behavioral profile…" />
  )

  const hasFile = !!file

  return (
    <Reveal>
      {/* Drop zone */}
      <div
        onClick={() => document.getElementById("file-input").click()}
        style={{
          border: `2px dashed ${hasFile ? "#1d4ed8" : "#1e2438"}`,
          borderRadius: 16, padding: "52px 32px",
          textAlign: "center", marginBottom: 20, cursor: "pointer",
          background: hasFile ? "rgba(29,78,216,0.04)" : "#151922",
          transition: "all 0.2s",
          boxShadow: hasFile ? "inset 0 0 40px rgba(29,78,216,0.04)" : "none",
        }}>
        <input id="file-input" type="file" accept="*/*"
          style={{ display: "none" }}
          onChange={e => setFile(e.target.files[0])} />
        {hasFile ? (
          <>
            <div style={{ fontSize: 36, marginBottom: 12 }}>🎵</div>
            <p style={{ fontWeight: 600, margin: "0 0 4px", color: "#f0eeff", fontSize: 15 }}>
              {file.name}
            </p>
            <p style={{ fontSize: 13, color: "#8b89aa", margin: 0 }}>
              {(file.size / 1024 / 1024).toFixed(1)} MB · Click to change
            </p>
          </>
        ) : (
          <>
            <div style={{ fontSize: 44, marginBottom: 14 }}>🎙️</div>
            <p style={{ fontWeight: 600, margin: "0 0 6px", color: "#f0eeff", fontSize: 16 }}>
              Drop audio or video here
            </p>
            <p style={{ fontSize: 13, color: "#4a4865", margin: 0 }}>
              .mp3 · .wav · .m4a · .mp4 · up to 100 MB
            </p>
          </>
        )}
      </div>

      {!serverWarm && (
        <div style={{ background: "rgba(245,158,11,0.07)",
          border: "1px solid rgba(245,158,11,0.2)",
          borderRadius: 8, padding: "10px 14px", marginBottom: 14,
          fontSize: 12, color: "#f59e0b", display: "flex", alignItems: "center", gap: 8 }}>
          <span style={{ fontSize: 14 }}>⏳</span>
          Server is waking up — first analysis may take a little longer than usual.
        </div>
      )}

      {usage && (
        <div style={{ marginBottom: 14 }}>
          <div style={{ display: "flex", justifyContent: "space-between",
            alignItems: "center", marginBottom: 6 }}>
            <span style={{ fontSize: 12, color: "#4a4865" }}>
              Sessions this month
            </span>
            <span style={{ fontSize: 12, fontWeight: 600,
              color: usage.remaining === 0 ? "#f87171" : usage.remaining <= 3 ? "#fb923c" : "#4a4865" }}>
              {usage.used} / {usage.limit}
            </span>
          </div>
          <div style={{ height: 3, background: "#1e2438", borderRadius: 2, overflow: "hidden" }}>
            <div style={{
              height: "100%", borderRadius: 2,
              width: `${Math.min((usage.used / usage.limit) * 100, 100)}%`,
              background: usage.remaining === 0 ? "#f87171"
                : usage.remaining <= 3 ? "#fb923c" : G,
              transition: "width 0.5s ease",
            }} />
          </div>
          {usage.remaining === 0 && (
            <p style={{ fontSize: 12, color: "#f87171", margin: "6px 0 0" }}>
              Limit reached — resets {usage.resets_on}
            </p>
          )}
        </div>
      )}

      {error && (
        <div style={{ background: "rgba(248,113,113,0.08)",
          border: "1px solid rgba(248,113,113,0.25)",
          borderRadius: 8, padding: 12, marginBottom: 16,
          fontSize: 13, color: "#f87171" }}>
          ⚠️ {error}
        </div>
      )}

      <button onClick={handlePrepare} disabled={!hasFile || usage?.remaining === 0}
        className={hasFile ? "btn-grad" : ""}
        style={{ width: "100%", padding: "15px 24px",
          background: hasFile ? G : "#151922",
          color: hasFile ? "white" : "#2a2a42",
          border: hasFile ? "none" : "1px solid #1e2438",
          borderRadius: 10, fontSize: 15,
          cursor: hasFile ? "pointer" : "not-allowed", fontWeight: 600,
          boxShadow: hasFile ? "0 0 28px rgba(29,78,216,0.3)" : "none" }}>
        Analyze Conversation
      </button>

      <div style={{ marginTop: 14, padding: "10px 14px",
        background: "rgba(29,78,216,0.06)", border: "1px solid rgba(29,78,216,0.15)",
        borderRadius: 8, textAlign: "center" }}>
        <p style={{ fontSize: 12, color: "#6b6a8a", margin: 0 }}>
          🔒 Audio is deleted immediately after analysis. Only behavioural insights are stored.{" "}
          <a href="https://harsh200415-mirror-backend.hf.space/privacy"
            target="_blank" rel="noreferrer"
            style={{ color: "#5b9cf6", textDecoration: "none" }}>
            Privacy Policy
          </a>
        </p>
      </div>
    </Reveal>
  )
}
