/**
 * chatApiService.ts — Client HTTP para o novo backend NewWhats.
 * Consumido pelo chatStore e pelos componentes React.
 */
import axios, { type AxiosInstance } from 'axios'

const API = process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:3003'

function createClient(): AxiosInstance {
  const client = axios.create({ baseURL: API })

  client.interceptors.request.use((config) => {
    const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null
    if (token) config.headers.Authorization = `Bearer ${token}`
    return config
  })

  // Renova token automaticamente em 401
  client.interceptors.response.use(
    (r) => r,
    async (error) => {
      const original = error.config
      if (error.response?.status === 401 && !original._retry) {
        original._retry = true
        try {
          const refreshToken = localStorage.getItem('refreshToken')
          if (!refreshToken) throw new Error('Sem refresh token')
          const { data } = await axios.post(`${API}/api/auth/refresh`, { refreshToken })
          localStorage.setItem('token', data.accessToken)
          if (typeof window !== 'undefined') {
            document.cookie = `accessToken=${data.accessToken}; path=/; SameSite=Lax; Secure`
          }
          localStorage.setItem('refreshToken', data.refreshToken)
          original.headers.Authorization = `Bearer ${data.accessToken}`
          return client(original)
        } catch {
          localStorage.removeItem('token')
          localStorage.removeItem('refreshToken')
          if (typeof window !== 'undefined') {
            document.cookie = 'accessToken=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'
          }
          window.location.href = '/login'
        }
      }
      return Promise.reject(error)
    }
  )

  return client
}

export const api = createClient()

// ─── Auth ─────────────────────────────────────────────────────────────────────

export const authApi = {
  register: (data: { name: string; email: string; password: string }) =>
    api.post('/api/auth/register', data).then((r) => r.data),

  login: (data: { email: string; password: string }) =>
    api.post('/api/auth/login', data).then((r) => r.data),

  logout: () =>
    api.post('/api/auth/logout').then((r) => r.data),

  me: () =>
    api.get('/api/auth/me').then((r) => r.data),

  changePassword: (data: { currentPassword: string; newPassword: string }) =>
    api.patch('/api/auth/password', data).then((r) => r.data),
}

// ─── Instâncias ───────────────────────────────────────────────────────────────

export const instanceApi = {
  list: () =>
    api.get('/api/instances').then((r) => r.data),

  create: (name: string) =>
    api.post('/api/instances', { name }).then((r) => r.data),

  connect: (id: string) =>
    api.post(`/api/instances/${id}/connect`).then((r) => r.data),

  disconnect: (id: string) =>
    api.post(`/api/instances/${id}/disconnect`).then((r) => r.data),

  getQr: (id: string) =>
    api.get(`/api/instances/${id}/qr`).then((r) => r.data),

  delete: (id: string) =>
    api.delete(`/api/instances/${id}`).then((r) => r.data),
}

// ─── Chats ────────────────────────────────────────────────────────────────────

export const chatApi = {
  list: (instanceId: string, opts: { search?: string; archived?: boolean; limit?: number } = {}) =>
    api.get('/api/chats', { params: { instanceId, ...opts } }).then((r) => r.data),

  get: (chatId: string) =>
    api.get(`/api/chats/${chatId}`).then((r) => r.data),

  markRead: (chatId: string) =>
    api.post(`/api/chats/${chatId}/read`).then((r) => r.data),

  archive: (chatId: string, archived: boolean) =>
    api.patch(`/api/chats/${chatId}/archive`, { archived }).then((r) => r.data),

  pin: (chatId: string, pinned: boolean) =>
    api.patch(`/api/chats/${chatId}/pin`, { pinned }).then((r) => r.data),

  delete: (chatId: string) =>
    api.delete(`/api/chats/${chatId}`).then((r) => r.data),

  stats: (instanceId: string) =>
    api.get('/api/chats/stats/overview', { params: { instanceId } }).then((r) => r.data),
}

// ─── Mensagens ────────────────────────────────────────────────────────────────

export const messageApi = {
  list: (chatId: string, opts: { before?: string; after?: string; limit?: number } = {}) =>
    api.get(`/api/chats/${chatId}/messages`, { params: opts }).then((r) => r.data) as
      Promise<{ messages: any[]; hasMore: boolean }>,

  search: (instanceId: string, q: string, limit?: number) =>
    api.get('/api/chats/search/messages', { params: { instanceId, q, limit } }).then((r) => r.data),

  send: (instanceId: string, jid: string, text: string, replyToMessageId?: string, mentions?: string[]) =>
    api.post(`/api/instances/${instanceId}/send`, { jid, text, replyToMessageId, ...(mentions?.length ? { mentions } : {}) }).then((r) => r.data),
}

// ─── Grupos ──────────────────────────────────────────────────────────────────

export interface GroupParticipant {
  jid: string
  admin: string | null
  name: string | null
  phone: string
}

export const groupApi = {
  getParticipants: (instanceId: string, groupJid: string) =>
    api.get(`/api/instances/${instanceId}/groups/${encodeURIComponent(groupJid)}/participants`).then((r) => r.data) as
      Promise<{ groupJid: string; subject: string; participants: GroupParticipant[] }>,
}

// ─── Reconciliação ───────────────────────────────────────────────────────────

export const reconcileApi = {
  reconcileNames: (instanceId: string) =>
    api.post(`/api/instances/${instanceId}/reconcile-names`).then((r) => r.data) as
      Promise<{ updated: number } | void>,
}

// ─── Protocolos ───────────────────────────────────────────────────────────────

export const protocolApi = {
  list: (chatId: string) =>
    api.get(`/api/chats/${chatId}/protocol`).then((r) => r.data),

  open: (chatId: string, data: { sectorId?: string; teamId?: string }) =>
    api.post(`/api/chats/${chatId}/protocol`, data).then((r) => r.data),

  update: (chatId: string, protocolId: string, data: {
    status?: string
    summary?: string
  }) =>
    api.patch(`/api/chats/${chatId}/protocol/${protocolId}`, data).then((r) => r.data),
}

// ─── Mídia ────────────────────────────────────────────────────────────────────

export const mediaApi = {
  sendMedia: (
    instanceId: string,
    jid: string,
    file: File,
    caption?: string,
    replyToMessageId?: string
  ) => {
    const fd = new FormData()
    fd.append('file', file)
    fd.append('jid', jid)
    if (caption) fd.append('caption', caption)
    if (replyToMessageId) fd.append('replyToMessageId', replyToMessageId)
    return api
      .post(`/api/instances/${instanceId}/send-media`, fd, {
        headers: { 'Content-Type': 'multipart/form-data' },
      })
      .then((r) => r.data)
  },

  sendAudio: (instanceId: string, jid: string, blob: Blob) => {
    const fd = new FormData()
    fd.append('audio', blob, 'audio.ogg')
    fd.append('jid', jid)
    return api
      .post(`/api/instances/${instanceId}/send-audio`, fd, {
        headers: { 'Content-Type': 'multipart/form-data' },
      })
      .then((r) => r.data)
  },

  sendSticker: (instanceId: string, jid: string, blob: Blob) => {
    const fd = new FormData()
    fd.append('file', blob, 'sticker.webp')
    fd.append('jid', jid)
    return api
      .post(`/api/instances/${instanceId}/send-media`, fd, {
        headers: { 'Content-Type': 'multipart/form-data' },
      })
      .then((r) => r.data)
  },

  redownload: (instanceId: string, messageDbId: string): Promise<{ mediaUrl: string }> =>
    api.post(`/api/instances/${instanceId}/redownload-media/${messageDbId}`).then((r) => r.data),
}

// ─── Chatbot / IA ─────────────────────────────────────────────────────────────

export const chatbotApi = {
  getCredentials: (instanceId: string) =>
    api.get(`/api/chatbot/credentials/${instanceId}`).then((r) => r.data),

  createCredential: (instanceId: string, data: { name: string; apiKey: string; provider?: 'GEMINI' | 'OPENAI' }) =>
    api.post(`/api/chatbot/credentials/${instanceId}`, data).then((r) => r.data),

  deleteCredential: (instanceId: string, credId: string) =>
    api.delete(`/api/chatbot/credentials/${instanceId}/${credId}`).then((r) => r.data),

  getBots: (instanceId: string) =>
    api.get(`/api/chatbot/bots/${instanceId}`).then((r) => r.data),

  createBot: (instanceId: string, data: Record<string, unknown>) =>
    api.post(`/api/chatbot/bots/${instanceId}`, data).then((r) => r.data),

  updateBot: (instanceId: string, botId: string, data: Record<string, unknown>) =>
    api.put(`/api/chatbot/bots/${instanceId}/${botId}`, data).then((r) => r.data),

  deleteBot: (instanceId: string, botId: string) =>
    api.delete(`/api/chatbot/bots/${instanceId}/${botId}`).then((r) => r.data),

  pauseChat: (_instanceId: string, chatId: string) =>
    api.post(`/api/chatbot/chats/${chatId}/pause`).then((r) => r.data),

  resumeChat: (_instanceId: string, chatId: string) =>
    api.post(`/api/chatbot/chats/${chatId}/resume`).then((r) => r.data),
}

// ─── API Keys ─────────────────────────────────────────────────────────────────

export interface ApiKeyRecord {
  id: string
  name: string
  keyPreview: string   // '••••••••XXXXXXXX'
  isActive: boolean
  createdAt: string
  expiresAt: string | null
}

export const apiKeyApi = {
  list: () =>
    api.get('/api/api-keys').then((r) => r.data) as Promise<ApiKeyRecord[]>,

  create: (name: string, expiresAt?: string) =>
    api.post('/api/api-keys', { name, expiresAt }).then((r) => r.data) as
      Promise<{ id: string; name: string; key: string; isActive: boolean; createdAt: string; expiresAt: string | null }>,

  toggle: (id: string, isActive: boolean) =>
    api.patch(`/api/api-keys/${id}`, { isActive }).then((r) => r.data),

  delete: (id: string) =>
    api.delete(`/api/api-keys/${id}`).then((r) => r.data),
}

// ─── Setores e Equipes ────────────────────────────────────────────────────────

export interface Sector {
  id: string
  tenantId: string
  name: string
  isActive: boolean
  createdAt: string
  updatedAt: string
  _count?: { teams: number; protocols: number }
}

export interface Team {
  id: string
  tenantId: string
  sectorId: string
  name: string
  isActive: boolean
  createdAt: string
  updatedAt: string
  _count?: { protocols: number }
}

export const sectorApi = {
  list: () =>
    api.get('/api/sectors').then((r) => r.data) as Promise<Sector[]>,

  create: (name: string) =>
    api.post('/api/sectors', { name }).then((r) => r.data) as Promise<Sector>,

  update: (id: string, data: { name?: string; isActive?: boolean }) =>
    api.patch(`/api/sectors/${id}`, data).then((r) => r.data) as Promise<Sector>,

  delete: (id: string) =>
    api.delete(`/api/sectors/${id}`).then((r) => r.data),

  listTeams: (sectorId: string) =>
    api.get(`/api/sectors/${sectorId}/teams`).then((r) => r.data) as Promise<Team[]>,

  createTeam: (sectorId: string, name: string) =>
    api.post(`/api/sectors/${sectorId}/teams`, { name }).then((r) => r.data) as Promise<Team>,

  updateTeam: (sectorId: string, teamId: string, data: { name?: string; isActive?: boolean }) =>
    api.patch(`/api/sectors/${sectorId}/teams/${teamId}`, data).then((r) => r.data) as Promise<Team>,

  deleteTeam: (sectorId: string, teamId: string) =>
    api.delete(`/api/sectors/${sectorId}/teams/${teamId}`).then((r) => r.data),
}

// ─── Contatos / Phonebook ─────────────────────────────────────────────────────

export interface BackendContact {
  id: string
  instanceId: string
  jid: string
  name: string | null
  verifiedName: string | null
  notify: string | null
  phone: string | null
  avatarUrl: string | null
  scoreReputacao: number
  flagRestricao: boolean
  isBlocked: boolean
  createdAt: string
  updatedAt: string
}

export const contactApi = {
  list: (opts: { instanceId?: string; search?: string; blocked?: boolean; limit?: number; offset?: number } = {}) =>
    api.get('/api/contacts', { params: opts }).then((r) => r.data) as
      Promise<{ total: number; contacts: BackendContact[] }>,

  get: (id: string) =>
    api.get(`/api/contacts/${id}`).then((r) => r.data) as Promise<BackendContact>,

  update: (id: string, data: { name?: string; isBlocked?: boolean }) =>
    api.patch(`/api/contacts/${id}`, data).then((r) => r.data) as Promise<BackendContact>,

  delete: (id: string) =>
    api.delete(`/api/contacts/${id}`).then((r) => r.data),

  stats: (instanceId?: string) =>
    api.get('/api/contacts/stats/overview', { params: instanceId ? { instanceId } : undefined }).then((r) => r.data) as
      Promise<{ total: number; blocked: number; flagged: number; active: number }>,
}

// ─── Broadcast ───────────────────────────────────────────────────────────────

export const broadcastApi = {
  create: (instanceId: string, data: { numbers: string[]; message: string; delayMs?: number }) =>
    api.post(`/api/instances/${instanceId}/broadcast`, data).then((r) => r.data) as
      Promise<{ jobId: string; total: number }>,

  list: (instanceId: string, limit = 20) =>
    api.get(`/api/instances/${instanceId}/broadcast`, { params: { limit } }).then((r) => r.data) as
      Promise<Array<{
        id: string; status: string; message: string
        totalCount: number; sentCount: number; failedCount: number
        createdAt: string; finishedAt: string | null
        _count: { recipients: number }
      }>>,

  get: (instanceId: string, broadcastId: string) =>
    api.get(`/api/instances/${instanceId}/broadcast/${broadcastId}`).then((r) => r.data),
}

// ─── Plano ────────────────────────────────────────────────────────────────────

export const planApi = {
  status: () =>
    api.get('/api/plan/status').then((r) => r.data) as
      Promise<{ daysRemaining: number | null; planName: string }>,
}

// ─── Mensagens Ricas (tipos avançados de WhatsApp) ────────────────────────────

export interface RichPayload {
  text?:            string
  footer?:          string
  nativeButtons?:   Array<{ type: string; id?: string; text: string; url?: string; copyText?: string; phoneNumber?: string }>
  nativeList?:      { buttonText: string; sections: Array<{ title: string; rows: Array<{ id: string; title: string; description?: string }> }> }
  nativeCarousel?:  { cards: Array<{ title?: string; body?: string; footer?: string; image?: { url: string }; buttons: Array<{ type?: string; id?: string; text: string }> }> }
  poll?:            { name: string; values: string[]; selectableCount?: number }
}

export const richMessageApi = {
  send: (instanceId: string, jid: string, payload: RichPayload) =>
    api.post(`/api/instances/${instanceId}/send`, { jid, ...payload }).then((r) => r.data),
}

// ─── Templates de Mensagem ────────────────────────────────────────────────────

export type TemplateType = 'TEXT' | 'BUTTONS' | 'INTERACTIVE' | 'LIST' | 'POLL' | 'CAROUSEL'

export interface MessageTemplate {
  id:          string
  tenantId:    string
  name:        string
  description: string | null
  type:        TemplateType
  payload:     Record<string, unknown>
  tags:        string[]
  usageCount:  number
  createdAt:   string
  updatedAt:   string
}

export const templateApi = {
  list: (opts: { type?: TemplateType; search?: string } = {}) =>
    api.get('/api/templates', { params: opts }).then((r) => r.data) as Promise<MessageTemplate[]>,

  get: (id: string) =>
    api.get(`/api/templates/${id}`).then((r) => r.data) as Promise<MessageTemplate>,

  create: (data: { name: string; description?: string; type: TemplateType; payload: Record<string, unknown>; tags?: string[] }) =>
    api.post('/api/templates', data).then((r) => r.data) as Promise<MessageTemplate>,

  update: (id: string, data: Partial<{ name: string; description: string; type: TemplateType; payload: Record<string, unknown>; tags: string[] }>) =>
    api.put(`/api/templates/${id}`, data).then((r) => r.data) as Promise<MessageTemplate>,

  delete: (id: string) =>
    api.delete(`/api/templates/${id}`).then((r) => r.data),

  markUsed: (id: string) =>
    api.post(`/api/templates/${id}/use`).then((r) => r.data),
}

// ─── Agendamentos de Mensagem ─────────────────────────────────────────────────

export type ScheduleType   = 'ONCE' | 'RECURRING' | 'EVENT'
export type ScheduleStatus = 'ACTIVE' | 'PAUSED' | 'DONE' | 'CANCELLED'
export type EventType      = 'BIRTHDAY' | 'ANNIVERSARY' | 'SIGNUP_DAYS'
export type RecipientMode  = 'MANUAL' | 'ALL_CONTACTS' | 'TAG_FILTER'

export interface ScheduleRecipient {
  jid:          string
  name?:        string
  birthday?:    string
  anniversary?: string
  signupDate?:  string
}

export interface ScheduledMessage {
  id:            string
  tenantId:      string
  instanceId:    string
  name:          string
  templateId:    string | null
  payload:       Record<string, unknown>
  recipientMode: RecipientMode
  recipients:    ScheduleRecipient[]
  scheduleType:  ScheduleType
  cronExpr:      string | null
  scheduledAt:   string | null
  eventType:     EventType | null
  timezone:      string
  status:        ScheduleStatus
  lastRunAt:     string | null
  nextRunAt:     string | null
  runCount:      number
  createdAt:     string
  updatedAt:     string
  template?:     Pick<MessageTemplate, 'id' | 'name' | 'type'> | null
  _count?:       { logs: number }
}

export interface ScheduleLog {
  id:          string
  scheduleId:  string
  status:      string
  sentCount:   number
  failedCount: number
  error:       string | null
  runAt:       string
}

export const scheduleApi = {
  list: (opts: { status?: ScheduleStatus; type?: ScheduleType } = {}) =>
    api.get('/api/scheduled', { params: opts }).then((r) => r.data) as Promise<ScheduledMessage[]>,

  get: (id: string) =>
    api.get(`/api/scheduled/${id}`).then((r) => r.data) as Promise<ScheduledMessage>,

  create: (data: {
    instanceId:    string
    name:          string
    templateId?:   string
    payload:       Record<string, unknown>
    recipientMode?: RecipientMode
    recipients?:   ScheduleRecipient[]
    scheduleType:  ScheduleType
    cronExpr?:     string
    scheduledAt?:  string
    eventType?:    EventType
    timezone?:     string
  }) =>
    api.post('/api/scheduled', data).then((r) => r.data) as Promise<ScheduledMessage>,

  update: (id: string, data: Partial<Parameters<typeof scheduleApi.create>[0]>) =>
    api.put(`/api/scheduled/${id}`, data).then((r) => r.data) as Promise<ScheduledMessage>,

  delete: (id: string) =>
    api.delete(`/api/scheduled/${id}`).then((r) => r.data),

  pause: (id: string) =>
    api.post(`/api/scheduled/${id}/pause`).then((r) => r.data),

  resume: (id: string) =>
    api.post(`/api/scheduled/${id}/resume`).then((r) => r.data),

  runNow: (id: string) =>
    api.post(`/api/scheduled/${id}/run-now`).then((r) => r.data),

  logs: (id: string) =>
    api.get(`/api/scheduled/${id}/logs`).then((r) => r.data) as Promise<ScheduleLog[]>,
}

// ─── Stickers ─────────────────────────────────────────────────────────────────

export interface StickerRecord {
  id:         string
  sha256:     string
  wasabiPath: string
  isAnimated: boolean
  isFavorite: boolean
  useCount?:  number
  lastSeenAt?: string
}

export const stickerApi = {
  list: () =>
    api.get('/api/stickers').then((r) => r.data) as Promise<{ listVersion: string; stickers: StickerRecord[] }>,

  recent: () =>
    api.get('/api/stickers/recent').then((r) => r.data) as Promise<{ stickers: StickerRecord[] }>,

  toggleFavorite: (id: string) =>
    api.patch(`/api/stickers/${id}/favorite`).then((r) => r.data) as Promise<{ id: string; isFavorite: boolean }>,
}
