"use client"

import Link from "next/link"
import { useEffect, useRef, useState } from "react"
import { useParams } from "next/navigation"
import { useLocale, useTranslations } from "next-intl"
import { ArrowLeft, RefreshCw, FolderOpen, Eye, EyeOff } from "lucide-react"

import {
  listTenantCaseMessages,
  sendTenantCaseMessage,
  patchTenantCaseMessage,
  deleteTenantCaseMessage,
  markTenantMessageRead,
  getTenantTyping,
  setTenantTyping,
  clearTenantTyping,
} from "@/src/lib/api/tenant-messages"
import type { CaseMessage } from "@/src/lib/api/customer-portal"
import { MessageThread, type Msg } from "@/src/components/messaging/MessageThread"
import { api } from "@/src/lib/api/client"
import {
  type CallSession,
  getTenantActiveCall,
  startTenantCall,
  endTenantCall,
} from "@/src/lib/api/calls"

const NAVY  = "#1a3578"
const NAVY2 = "#2655b0"
const TEAL  = "#4dba96"

function toMsg(m: CaseMessage): Msg { return m as unknown as Msg }

type CaseDetail = {
  id: number
  reference: string
  title?: string
  status?: string
  customer?: { id: number; name: string } | null
}

type Visibility = "all" | "shared" | "internal"

export default function TenantCaseThreadPage() {
  const locale  = useLocale()
  const t       = useTranslations("communications")
  const params  = useParams<{ caseId: string }>()
  const caseId  = Number(params?.caseId)

  const [me, setMe]               = useState<{ id: number; username: string } | null>(null)
  const [caseItem, setCaseItem]   = useState<CaseDetail | null>(null)
  const [messages, setMessages]   = useState<CaseMessage[]>([])
  const [loading, setLoading]     = useState(true)
  const [sending, setSending]     = useState(false)
  const [error, setError]         = useState<string | null>(null)
  const [typingLabels, setTyping] = useState<string[]>([])
  const [visibility, setVisibility] = useState<Visibility>("all")
  const [newVisibility, setNewVisibility] = useState<"shared" | "internal">("shared")
  const [activeCall, setActiveCall] = useState<CallSession | null>(null)

  const pollRef   = useRef<ReturnType<typeof setInterval> | null>(null)
  const typingRef = useRef<ReturnType<typeof setInterval> | null>(null)
  const callRef   = useRef<ReturnType<typeof setInterval> | null>(null)

  // ── Load ──────────────────────────────────────────────────────────────────
  async function loadAll() {
    setLoading(true); setError(null)
    try {
      const [meData, msgs, cs] = await Promise.all([
        api.request<{ id: number; username: string }>("/auth/me/").catch(() => null),
        listTenantCaseMessages(caseId, visibility === "all" ? "" : visibility),
        api.request<CaseDetail>(`/cases/${caseId}/`).catch(() => null),
      ])
      setMe(meData)
      setMessages(msgs)
      setCaseItem(cs)
    } catch (e: any) {
      setError(e?.message || "Erreur de chargement.")
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    if (!caseId || isNaN(caseId)) return
    loadAll()
    getTenantActiveCall(caseId).then(setActiveCall).catch(() => {})
    pollRef.current   = setInterval(() => {
      listTenantCaseMessages(caseId, visibility === "all" ? "" : visibility)
        .then(msgs => setMessages(prev => {
          const serverIds = new Set(msgs.map((m: any) => m.id))
          const localOnly = prev.filter(m => !serverIds.has(m.id))
          return [...msgs, ...localOnly]
        }))
        .catch(() => {})
    }, 5000)
    typingRef.current = setInterval(() => {
      getTenantTyping(caseId).then(r => setTyping(r.typing)).catch(() => {})
    }, 2500)
    callRef.current   = setInterval(() => {
      getTenantActiveCall(caseId).then(setActiveCall).catch(() => {})
    }, 4000)
    return () => {
      if (pollRef.current)   clearInterval(pollRef.current)
      if (typingRef.current) clearInterval(typingRef.current)
      if (callRef.current)   clearInterval(callRef.current)
      clearTenantTyping(caseId).catch(() => {})
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [caseId, visibility])

  // ── Handlers ──────────────────────────────────────────────────────────────
  async function onSend({ body, files }: { body: string; files?: File[] }) {
    setSending(true); setError(null)
    try {
      const msg = await sendTenantCaseMessage(caseId, { body, visibility: newVisibility, files })
      setMessages(prev => {
        const exists = prev.some(m => m.id === msg.id)
        return exists ? prev.map(m => m.id === msg.id ? msg : m) : [...prev, msg]
      })
      clearTenantTyping(caseId).catch(() => {})
    } catch (e: any) { setError(e?.message || "Erreur envoi.") }
    finally { setSending(false) }
  }

  async function onEdit(msg: CaseMessage, newBody: string) {
    try {
      const updated = await patchTenantCaseMessage(caseId, msg.id, newBody)
      setMessages(prev => prev.map(m => m.id === updated.id ? updated : m))
    } catch (e: any) { setError(e?.message || "Erreur modification.") }
  }

  async function onDelete(msg: CaseMessage) {
    try {
      await deleteTenantCaseMessage(caseId, msg.id)
      setMessages(prev => prev.filter(m => m.id !== msg.id))
    } catch (e: any) { setError(e?.message || "Erreur suppression.") }
  }

  function onMarkRead(msgId: number) {
    markTenantMessageRead(caseId, msgId).catch(() => {})
    setMessages(prev => prev.map(m => m.id === msgId ? { ...m, is_read: true } : m))
  }

  async function handleStartCall(type: "audio" | "video") {
    try {
      const call = await startTenantCall(caseId, type)
      setActiveCall(call)
    } catch {}
  }

  async function handleEndCall() {
    if (!activeCall) return
    try {
      await endTenantCall(caseId, activeCall.id)
      setActiveCall(null)
    } catch {}
  }

  return (
    <div className="flex flex-col gap-3 h-[calc(100vh-6rem)]">

      {/* Header */}
      <div className="flex items-center justify-between gap-3 shrink-0">
        <div className="flex items-center gap-3 min-w-0">
          <Link href={`/${locale}/communications`}
            className="inline-flex items-center gap-1.5 rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm text-slate-600 hover:bg-slate-50 transition shadow-sm">
            <ArrowLeft className="h-4 w-4" />
            {t("thread.back")}
          </Link>
          <div className="min-w-0">
            <div className="flex items-center gap-2">
              <span className="font-bold text-base truncate" style={{ color: NAVY }}>
                {caseItem?.reference ?? `#${caseId}`}
              </span>
              {caseItem?.title && (
                <span className="text-sm text-slate-500 truncate hidden sm:block">— {caseItem.title}</span>
              )}
            </div>
            {caseItem?.customer?.name && (
              <div className="text-xs text-slate-400">{caseItem.customer.name}</div>
            )}
          </div>
        </div>

        <div className="flex items-center gap-2 shrink-0">
          {/* Visibility filter */}
          <div className="flex rounded-xl border border-slate-200 bg-white overflow-hidden text-xs shadow-sm">
            {(["all", "shared", "internal"] as Visibility[]).map(v => (
              <button key={v} onClick={() => setVisibility(v)}
                className="px-2.5 py-1.5 transition"
                style={visibility === v ? { background: NAVY, color: "#fff" } : { color: "#64748b" }}>
                {v === "all" ? t("thread.filter_all") : v === "shared" ? t("thread.filter_client") : t("thread.filter_internal")}
              </button>
            ))}
          </div>
          <button onClick={loadAll}
            className="inline-flex items-center gap-1.5 rounded-xl border border-slate-200 bg-white px-3 py-2 text-xs text-slate-600 hover:bg-slate-50 transition shadow-sm">
            <RefreshCw className="h-3.5 w-3.5" />
          </button>
          {caseItem && (
            <Link href={`/${locale}/cases/${caseId}`}
              className="inline-flex items-center gap-1.5 rounded-xl border border-slate-200 bg-white px-3 py-2 text-xs text-slate-600 hover:bg-slate-50 transition shadow-sm">
              <FolderOpen className="h-3.5 w-3.5" />
              {t("thread.case_link")}
            </Link>
          )}
        </div>
      </div>

      {/* Visibility selector for new messages */}
      <div className="shrink-0 flex items-center gap-3 rounded-xl border border-slate-200 bg-white px-4 py-2 shadow-sm text-sm">
        <span className="text-slate-500 text-xs font-medium uppercase tracking-wide">{t("thread.new_msg_label")}</span>
        <label className="flex items-center gap-1.5 cursor-pointer text-slate-600">
          <input type="radio" name="newvis" value="shared" className="accent-teal-500"
            checked={newVisibility === "shared"} onChange={() => setNewVisibility("shared")} />
          <Eye className="h-3.5 w-3.5" style={{ color: TEAL }} />
          {t("thread.visible_client")}
        </label>
        <label className="flex items-center gap-1.5 cursor-pointer text-slate-600">
          <input type="radio" name="newvis" value="internal" className="accent-amber-500"
            checked={newVisibility === "internal"} onChange={() => setNewVisibility("internal")} />
          <EyeOff className="h-3.5 w-3.5 text-amber-500" />
          {t("thread.internal_only")}
        </label>
      </div>

      {/* Thread */}
      <div className="flex-1 min-h-0">
        <MessageThread
          myUserId={me?.id ?? null}
          mySide="tenant"
          messages={messages.map(toMsg)}
          loading={loading}
          sending={sending}
          error={error ?? undefined}
          typingLabels={typingLabels}
          onSend={onSend as any}
          onEdit={onEdit as any}
          onDelete={onDelete as any}
          onMarkRead={onMarkRead}
          onTyping={() => setTenantTyping(caseId).catch(() => {})}
          onStopTyping={() => clearTenantTyping(caseId).catch(() => {})}
          accentColor={NAVY2}
          myBubbleColor={NAVY}
          otherBubbleColor="#e8f5f0"
          placeholder={newVisibility === "internal" ? t("thread.placeholder_internal") : t("thread.placeholder_shared")}
          labels={{
            loading:       t("thread.loading"),
            noMessages:    t("thread.no_messages"),
            save:          t("thread.edit"),
            cancel:        t("thread.cancel" as any),
            editingLabel:  t("thread.editing_label" as any),
            recording:     t("thread.recording" as any),
            stopRecording: t("thread.stop_recording" as any),
            joinCall:      t("thread.join_call" as any),
            callAudio:     t("thread.call_audio" as any),
            callVideo:     t("thread.call_video" as any),
            attachFile:    t("thread.attach_file" as any),
            voiceMsg:      t("thread.voice_msg" as any),
            stopRecord:    t("thread.stop_record" as any),
            agentBadge:    t("thread.agent_badge" as any),
            internalBadge: t("thread.internal_badge" as any),
            typingOne:     t("thread.typing_one" as any),
            typingMany:    t("thread.typing_many" as any),
            confirmDelete: t("thread.confirmDelete"),
          }}
          activeCall={activeCall}
          myCallDisplayName={me?.username ?? "Agent"}
          onStartCall={handleStartCall}
          onEndCall={handleEndCall}
        />
      </div>
    </div>
  )
}
