import { NextRequest, NextResponse } from 'next/server'
import { imChannelRepo } from '@/lib/database/repositories/im-channel.repo'
import { initDeviceFlow, beginAuth, pollAuth } from '@/lib/im/adapters/dingtalk/auth'

function normalizeQrLoginStatus(status?: string | null): 'pending' | 'scanned' | 'confirmed' | 'expired' {
  if (status === 'SUCCESS') return 'confirmed'
  if (status === 'FAIL') return 'expired'
  if (status === 'EXPIRED') return 'expired'
  return 'pending'
}

export async function POST(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  const { id } = await params

  let body: { action?: string; nonce?: string; device_code?: string }
  try { body = await req.json() } catch { return NextResponse.json({ error: 'Invalid JSON' }, { status: 400 }) }

  const action = body.action
  if (action !== 'init' && action !== 'begin' && action !== 'poll') {
    return NextResponse.json({ error: 'action must be "init", "begin", or "poll"' }, { status: 400 })
  }

  // Validate channel exists and is dingtalk
  const channel = imChannelRepo.findById(id)
  if (!channel) return NextResponse.json({ error: 'Channel not found' }, { status: 404 })
  if (channel.type !== 'dingtalk') {
    return NextResponse.json({ error: 'Channel is not a DingTalk channel' }, { status: 400 })
  }

  try {
    if (action === 'init') {
      const resp = await initDeviceFlow('openClaw')
      if (resp.errcode !== 0) {
        return NextResponse.json({ error: resp.errmsg || 'Failed to init device flow' }, { status: 500 })
      }
      if (!resp.nonce) {
        return NextResponse.json({ error: 'No nonce returned' }, { status: 500 })
      }
      return NextResponse.json({
        status: 'pending',
        nonce: resp.nonce,
        expires_in: resp.expires_in,
      })
    } else if (action === 'begin') {
      const nonce = body.nonce
      if (!nonce) {
        return NextResponse.json({ error: 'nonce is required for begin' }, { status: 400 })
      }

      const resp = await beginAuth(nonce)
      if (resp.errcode !== 0) {
        return NextResponse.json({ error: resp.errmsg || 'Failed to begin auth' }, { status: 500 })
      }
      if (!resp.device_code || !resp.verification_uri_complete) {
        return NextResponse.json({ error: 'No device_code or verification_uri returned' }, { status: 500 })
      }

      return NextResponse.json({
        status: 'pending',
        device_code: resp.device_code,
        user_code: resp.user_code,
        verification_uri: resp.verification_uri,
        verification_uri_complete: resp.verification_uri_complete,
        expires_in: resp.expires_in,
        interval: resp.interval,
      })
    } else {
      // action === 'poll'
      const deviceCode = body.device_code
      if (!deviceCode) {
        return NextResponse.json({ error: 'device_code is required for poll' }, { status: 400 })
      }

      const resp = await pollAuth(deviceCode)
      if (resp.errcode !== 0) {
        return NextResponse.json({ error: resp.errmsg || 'Failed to poll auth status' }, { status: 500 })
      }

      const status = normalizeQrLoginStatus(resp.status)
      if (status === 'confirmed') {
        const clientId = resp.client_id
        const clientSecret = resp.client_secret

        if (!clientId) {
          return NextResponse.json({ error: 'Auth confirmed but no client_id received' }, { status: 500 })
        }

        return NextResponse.json({
          status: 'confirmed',
          client_id: clientId,
          client_secret: clientSecret,
        })
      }

      return NextResponse.json({
        status,
        fail_reason: resp.fail_reason,
      })
    }
  } catch (err) {
    const errorMsg = err instanceof Error ? err.message : 'Unknown error'
    return NextResponse.json({ error: errorMsg }, { status: 500 })
  }
}
