import { FastifyInstance } from "fastify"
import { OpenCodeZenClient, type ChatRequest, getDefaultZenConfig } from "../../integrations/opencode-zen"
import { Logger } from "../../logger"

interface OpenCodeZenRouteDeps {
    logger: Logger
}

export async function registerOpenCodeZenRoutes(
    app: FastifyInstance,
    deps: OpenCodeZenRouteDeps
) {
    const logger = deps.logger.child({ component: "opencode-zen-routes" })

    // Create shared client
    const client = new OpenCodeZenClient(getDefaultZenConfig())

    // List available free Zen models
    app.get('/api/opencode-zen/models', async (request, reply) => {
        try {
            const models = await client.getModels()

            return {
                models: models.map(m => ({
                    id: m.id,
                    name: m.name,
                    family: m.family,
                    provider: "opencode-zen",
                    free: true,
                    reasoning: m.reasoning,
                    tool_call: m.tool_call,
                    limit: m.limit
                }))
            }
        } catch (error) {
            logger.error({ error }, "Failed to list OpenCode Zen models")
            return reply.status(500).send({ error: "Failed to list models" })
        }
    })

    // Test connection
    app.get('/api/opencode-zen/test', async (request, reply) => {
        try {
            const connected = await client.testConnection()
            return { connected }
        } catch (error) {
            logger.error({ error }, "OpenCode Zen connection test failed")
            return reply.status(500).send({ error: "Connection test failed" })
        }
    })

    // Chat completion endpoint
    app.post('/api/opencode-zen/chat', async (request, reply) => {
        try {
            const chatRequest = request.body as ChatRequest

            // Handle streaming
            if (chatRequest.stream) {
                reply.raw.writeHead(200, {
                    'Content-Type': 'text/event-stream',
                    'Cache-Control': 'no-cache',
                    'Connection': 'keep-alive',
                })

                try {
                    for await (const chunk of client.chatStream(chatRequest)) {
                        reply.raw.write(`data: ${JSON.stringify(chunk)}\n\n`)

                        // Check for finish
                        if (chunk.choices?.[0]?.finish_reason) {
                            reply.raw.write('data: [DONE]\n\n')
                            break
                        }
                    }

                    reply.raw.end()
                } catch (streamError) {
                    logger.error({ error: streamError }, "OpenCode Zen streaming failed")
                    reply.raw.write(`data: ${JSON.stringify({ error: String(streamError) })}\n\n`)
                    reply.raw.end()
                }
            } else {
                const response = await client.chat(chatRequest)
                return response
            }
        } catch (error) {
            logger.error({ error }, "OpenCode Zen chat request failed")
            return reply.status(500).send({ error: "Chat request failed" })
        }
    })

    logger.info("OpenCode Zen routes registered - Free models available!")
}
