import { useState, useCallback, useEffect, useMemo } from 'react'
import { useInstanceStore } from '../store/instanceStore'
import { broadcastApi } from '../services/chatApiService'

// ─── Types ────────────────────────────────────────────────────────────────────

export interface BroadcastJob {
  id: string
  status: 'RUNNING' | 'DONE' | 'FAILED'
  message: string
  totalCount: number
  sentCount: number
  failedCount: number
  createdAt: string
  finishedAt: string | null
  _count: { recipients: number }
}

// ─── Hook ─────────────────────────────────────────────────────────────────────

export function useSendingLogic() {
  // Selectors granulares: cada um re-renderiza apenas quando o slice muda,
  // sem capturar o objeto inteiro do store (evita re-renders por mudanças em
  // outros slices como qrByInstance, loading, etc.)
  const instances        = useInstanceStore((s) => s.instances)
  const activeInstanceId = useInstanceStore((s) => s.activeInstanceId)
  const setActiveInstance = useInstanceStore((s) => s.setActiveInstance)
  const loadInstances    = useInstanceStore((s) => s.loadInstances)

  // ── Form state ────────────────────────────────────────────────────────────
  const [numbersRaw, setNumbersRaw] = useState('')
  const [message, setMessage] = useState('')
  const [delayMs, setDelayMs] = useState(2000)

  // ── Jobs list ─────────────────────────────────────────────────────────────
  const [jobs, setJobs] = useState<BroadcastJob[]>([])
  const [jobsLoading, setJobsLoading] = useState(false)

  // ── Submission state ──────────────────────────────────────────────────────
  const [submitting, setSubmitting] = useState(false)
  const [toast, setToast] = useState<{ message: string; type: 'success' | 'error' } | null>(null)

  const showToast = useCallback((message: string, type: 'success' | 'error') => {
    setToast({ message, type })
    setTimeout(() => setToast(null), 3500)
  }, [])

  const connectedInstances = useMemo(
    () => instances.filter((i) => i.status === 'CONNECTED'),
    [instances],
  )

  const activeInstance = useMemo(
    () => instances.find((i) => i.id === activeInstanceId) ?? null,
    [instances, activeInstanceId],
  )

  const uniqueNumbers = useMemo(() => {
    const parsed = numbersRaw
      .split(/[\n,;]+/)
      .map((n) => n.trim().replace(/\D/g, ''))
      .filter((n) => n.length >= 5)
    return Array.from(new Set(parsed))
  }, [numbersRaw])

  // ── Load jobs ─────────────────────────────────────────────────────────────
  const loadJobs = useCallback(async () => {
    if (!activeInstanceId) return
    setJobsLoading(true)
    try {
      const data = await broadcastApi.list(activeInstanceId)
      setJobs(data as BroadcastJob[])
    } catch {
      // silently ignore
    } finally {
      setJobsLoading(false)
    }
  }, [activeInstanceId])

  useEffect(() => {
    loadInstances()
  }, [])

  useEffect(() => {
    if (activeInstanceId) loadJobs()
  }, [activeInstanceId, loadJobs])

  // ── Poll running jobs ─────────────────────────────────────────────────────
  useEffect(() => {
    const hasRunning = jobs.some((j) => j.status === 'RUNNING')
    if (!hasRunning) return
    const id = setInterval(() => loadJobs(), 5000)
    return () => clearInterval(id)
  }, [jobs, loadJobs])

  // ── Contact picker ────────────────────────────────────────────────────────
  const [isPickerOpen, setIsPickerOpen] = useState(false)

  const addContactsToNumbers = useCallback((phones: string[]) => {
    if (phones.length === 0) return
    const cleaned = phones.map(p => p.replace(/\D/g, '')).filter(p => p.length >= 5)
    setNumbersRaw(prev => {
      const existing = prev.trim()
      const merged = existing ? `${existing}\n${cleaned.join('\n')}` : cleaned.join('\n')
      // Deduplica linhas
      const lines = Array.from(new Set(merged.split('\n').map(l => l.trim()).filter(Boolean)))
      return lines.join('\n')
    })
  }, [])

  // ── Submit ────────────────────────────────────────────────────────────────
  const handleSubmit = useCallback(async () => {
    if (!activeInstanceId) {
      showToast('Selecione uma instância conectada.', 'error')
      return
    }
    if (uniqueNumbers.length === 0) {
      showToast('Informe ao menos um número.', 'error')
      return
    }
    if (!message.trim()) {
      showToast('Informe a mensagem.', 'error')
      return
    }
    if (uniqueNumbers.length > 500) {
      showToast('Máximo de 500 números por disparo.', 'error')
      return
    }

    setSubmitting(true)
    try {
      const result = await broadcastApi.create(activeInstanceId, {
        numbers: uniqueNumbers,
        message: message.trim(),
        delayMs,
      })
      showToast(`Disparo iniciado! Job #${result.jobId.slice(0, 8)} — ${result.total} números.`, 'success')
      setNumbersRaw('')
      setMessage('')
      await loadJobs()
    } catch (err: any) {
      const msg = err?.response?.data?.error ?? 'Erro ao iniciar disparo.'
      showToast(msg, 'error')
    } finally {
      setSubmitting(false)
    }
  }, [activeInstanceId, uniqueNumbers, message, delayMs, loadJobs, showToast])

  const selectInstance = useCallback((id: string) => {
    setActiveInstance(id)
  }, [setActiveInstance])

  return {
    // instances
    connectedInstances,
    activeInstance,
    activeInstanceId,
    selectInstance,

    // form
    numbersRaw,
    setNumbersRaw,
    message,
    setMessage,
    delayMs,
    setDelayMs,
    parsedNumbers: uniqueNumbers,

    // jobs
    jobs,
    jobsLoading,
    loadJobs,

    // submit
    submitting,
    handleSubmit,

    // feedback
    toast,

    // contact picker
    isPickerOpen,
    setIsPickerOpen,
    addContactsToNumbers,
  }
}
