import {
  handleTelegramCallback,
  handleTelegramCommand,
  isAuthorizedTelegramChat,
} from '@/lib/telegram-panel-bot'
import { sendTelegramText } from '@/lib/telegram-bot-api'
import { formatUnauthorizedChat } from '@/lib/telegram-messages'

export type TelegramChatMessage = {
  chat: { id: number; type?: string; title?: string }
  from?: { id: number }
  sender_chat?: { id: number }
  text?: string
  entities?: Array<{ type: string; offset: number; length: number }>
}

export type TelegramUpdate = {
  update_id: number
  /** Private chats + groups */
  message?: TelegramChatMessage
  /** Channels post as channel_post (not message) */
  channel_post?: TelegramChatMessage
  edited_channel_post?: TelegramChatMessage
  callback_query?: {
    id: string
    data?: string
    from?: { id: number }
    message?: { chat: { id: number }; message_id: number }
  }
}

export type ProcessUpdateResult = {
  handled: 'command' | 'callback' | 'none'
  source?: 'message' | 'channel_post' | 'edited_channel_post' | 'callback_query'
  chatId?: string
  command?: string
}

function commandText(msg: TelegramChatMessage): string | null {
  const text = msg.text?.trim()
  if (!text) return null
  if (text.startsWith('/')) return text
  // Rare: entity says bot_command but trim/BOM quirks
  const entity = msg.entities?.find((e) => e.type === 'bot_command')
  if (entity && typeof entity.offset === 'number' && entity.length) {
    const slice = text.slice(entity.offset, entity.offset + entity.length).trim()
    if (slice.startsWith('/')) return slice
  }
  return null
}

async function processCommandMessage(
  msg: TelegramChatMessage,
  source: ProcessUpdateResult['source']
): Promise<ProcessUpdateResult> {
  const text = commandText(msg)
  if (!text) return { handled: 'none' }

  const chatId = msg.chat.id
  if (!isAuthorizedTelegramChat(chatId, msg.from?.id)) {
    console.warn('[telegram] Ignored command from unauthorized chat:', chatId, source)
    try {
      await sendTelegramText(formatUnauthorizedChat(), {
        chatId: String(chatId),
        parseMode: 'HTML',
      })
    } catch {
      /* ignore */
    }
    return {
      handled: 'none',
      source,
      chatId: String(chatId),
      command: text.split(/\s/)[0],
    }
  }

  await handleTelegramCommand(chatId, text)
  return {
    handled: 'command',
    source,
    chatId: String(chatId),
    command: text.split('@')[0]?.split(/\s/)[0],
  }
}

export async function processTelegramUpdate(
  update: TelegramUpdate
): Promise<ProcessUpdateResult> {
  // Prefer channel_post for channel setups (your case)
  if (update.channel_post) {
    const result = await processCommandMessage(update.channel_post, 'channel_post')
    if (result.handled === 'command' || commandText(update.channel_post)) return result
  }

  if (update.edited_channel_post) {
    const result = await processCommandMessage(
      update.edited_channel_post,
      'edited_channel_post'
    )
    if (result.handled === 'command' || commandText(update.edited_channel_post)) {
      return result
    }
  }

  if (update.message) {
    const result = await processCommandMessage(update.message, 'message')
    if (result.handled === 'command' || commandText(update.message)) return result
  }

  if (update.callback_query?.data && update.callback_query.message) {
    const chatId = update.callback_query.message.chat.id
    if (!isAuthorizedTelegramChat(chatId, update.callback_query.from?.id)) {
      console.warn('[telegram] Ignored callback from unauthorized chat:', chatId)
      return { handled: 'none', source: 'callback_query', chatId: String(chatId) }
    }
    await handleTelegramCallback(
      update.callback_query.id,
      chatId,
      update.callback_query.message.message_id,
      update.callback_query.data
    )
    return { handled: 'callback', source: 'callback_query', chatId: String(chatId) }
  }

  return { handled: 'none' }
}
