"use client"

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

import {
  getCustomerCase,
  listCustomerCaseMessages,
  sendCustomerCaseMessage,
  patchCustomerCaseMessage,
  deleteCustomerCaseMessage,
  markCustomerMessageRead,
  getPortalTyping,
  setPortalTyping,
  clearPortalTyping,
  getCustomerPortalMe,
  type CaseMessage,
  type CustomerPortalMe,
} from "@/src/lib/api/customer-portal"

import { MessageThread, type Msg } from "@/src/components/messaging/MessageThread"
import {
  type CallSession,
  getCustomerActiveCall,
  startCustomerCall,
  endCustomerCall,
} from "@/src/lib/api/calls"

// ── Type coercion ──────────────────────────────────────────────────────────
function toMsg(m: CaseMessage): Msg {
  return m as unknown as Msg
}

const TEAL = "#4dba96"
const NAVY = "#1a3578"

export default function ClientCaseThreadPage() {
  const locale = useLocale()
  const params = useParams<{ caseId: string }>()
  const caseId = Number(params?.caseId)

  const [me, setMe]               = useState<CustomerPortalMe | null>(null)
  const [caseItem, setCaseItem]   = useState<any>(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 [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 initial ──────────────────────────────────────────────────────────
  async function loadAll() {
    setLoading(true)
    setError(null)
    try {
      const [meData, msgs, cs] = await Promise.all([
        getCustomerPortalMe(),
        listCustomerCaseMessages(caseId),
        getCustomerCase(caseId).catch(() => null),
      ])
      setMe(meData)
      setMessages(msgs)
      setCaseItem(cs)
    } catch (e: any) {
      setError(e?.message || "Erreur de chargement.")
    } finally {
      setLoading(false)
    }
  }

  // ── Poll new messages every 5s ────────────────────────────────────────────
  async function pollMessages() {
    try {
      const msgs = await listCustomerCaseMessages(caseId)
      // Fusion : on garde les messages locaux non encore confirmés par le serveur
      setMessages(prev => {
        const serverIds = new Set(msgs.map(m => m.id))
        const localOnly = prev.filter(m => !serverIds.has(m.id))
        return [...msgs, ...localOnly]
      })
    } catch {}
  }

  // ── Poll typing every 2.5s ───────────────────────────────────────────────
  async function pollTyping() {
    try {
      const { typing } = await getPortalTyping(caseId)
      setTyping(typing)
    } catch {}
  }

  useEffect(() => {
    if (!caseId || isNaN(caseId)) return
    loadAll()

    getCustomerActiveCall(caseId).then(setActiveCall).catch(() => {})
    pollRef.current   = setInterval(pollMessages, 5000)
    typingRef.current = setInterval(pollTyping, 2500)
    callRef.current   = setInterval(() => {
      getCustomerActiveCall(caseId).then(setActiveCall).catch(() => {})
    }, 4000)

    return () => {
      if (pollRef.current)   clearInterval(pollRef.current)
      if (typingRef.current) clearInterval(typingRef.current)
      if (callRef.current)   clearInterval(callRef.current)
      clearPortalTyping(caseId).catch(() => {})
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [caseId])

  // ── Handlers ──────────────────────────────────────────────────────────────
  async function onSend({ body, files }: { body: string; files?: File[] }) {
    setSending(true)
    setError(null)
    try {
      const msg = await sendCustomerCaseMessage(caseId, { body, files })
      // Fusion dédupliquée pour éviter les doublons avec le poll
      setMessages(prev => {
        const exists = prev.some(m => m.id === msg.id)
        return exists ? prev.map(m => m.id === msg.id ? msg : m) : [...prev, msg]
      })
      clearPortalTyping(caseId).catch(() => {})
    } catch (e: any) {
      setError(e?.message || "Erreur envoi.")
    } finally {
      setSending(false)
    }
  }

  async function onEdit(msg: CaseMessage, newBody: string) {
    try {
      const updated = await patchCustomerCaseMessage(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 deleteCustomerCaseMessage(caseId, msg.id)
      setMessages(prev => prev.filter(m => m.id !== msg.id))
    } catch (e: any) {
      setError(e?.message || "Erreur suppression.")
    }
  }

  function onMarkRead(msgId: number) {
    markCustomerMessageRead(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 startCustomerCall(caseId, type)
      setActiveCall(call)
    } catch {}
  }

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

  const myUserId = me?.user?.id ?? null
  const caseRef  = caseItem?.reference ?? `#${caseId}`
  const caseTitle = caseItem?.title ?? ""

  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}/client/messages`}
            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" />
            Messages
          </Link>
          <div className="min-w-0">
            <div className="flex items-center gap-2">
              <span className="font-bold text-base truncate" style={{ color: NAVY }}>{caseRef}</span>
              {caseTitle && <span className="text-sm text-slate-500 truncate hidden sm:block">— {caseTitle}</span>}
            </div>
            {me?.customer?.name && (
              <div className="text-xs text-slate-400">{me.customer.name}</div>
            )}
          </div>
        </div>

        <div className="flex items-center gap-2 shrink-0">
          {caseItem && (
            <Link href={`/${locale}/client/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" />
              Voir le dossier
            </Link>
          )}
          <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>
        </div>
      </div>

      {/* Thread */}
      <div className="flex-1 min-h-0">
        <MessageThread
          myUserId={myUserId}
          mySide="customer"
          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={() => setPortalTyping(caseId).catch(() => {})}
          onStopTyping={() => clearPortalTyping(caseId).catch(() => {})}
          accentColor={TEAL}
          myBubbleColor={TEAL}
          otherBubbleColor="#e8f5f0"
          placeholder="Écrire un message au gestionnaire…"
          activeCall={activeCall}
          myCallDisplayName={me?.user?.username ?? "Client"}
          onStartCall={handleStartCall}
          onEndCall={handleEndCall}
        />
      </div>
    </div>
  )
}
