/**
 * Bot API Routes
 * 
 * POST /api/bots - Create a new bot
 * GET /api/bots - List user's bots
 * 
 * Requirements: 1.1, 1.3
 */

import { NextResponse } from 'next/server';
import { requireAuth } from '@/lib/auth';
import { z } from 'zod';
import {
  createBot,
  getBotsByUser,
  BotLimitExceededError,
  BotHandleTakenError,
  BotValidationError,
} from '@/lib/bots/botManager';

// Schema for creating a bot
const createBotSchema = z.object({
  name: z.string().min(1).max(100),
  handle: z.string().min(3).max(30).regex(/^[a-zA-Z0-9_]+$/, 'Handle must be alphanumeric and underscores only'),
  bio: z.string().max(500).optional(),
  avatarUrl: z.string().url().optional(),
  headerUrl: z.string().url().optional(),
  personality: z.object({
    systemPrompt: z.string().min(1).max(10000),
    temperature: z.number().min(0).max(2),
    maxTokens: z.number().int().min(1).max(100000),
    responseStyle: z.string().optional(),
  }),
  llmProvider: z.enum(['openrouter', 'openai', 'anthropic', 'custom']),
  llmModel: z.string().min(1),
  llmEndpoint: z.string().url().optional(),
  llmApiKey: z.string().min(1),
  schedule: z.object({
    type: z.enum(['interval', 'times', 'cron']),
    intervalMinutes: z.number().int().min(5).optional(),
    times: z.array(z.string().regex(/^([01][0-9]|2[0-3]):[0-5][0-9]$/)).optional(),
    cronExpression: z.string().optional(),
    timezone: z.string().optional(),
  }).optional(),
  autonomousMode: z.boolean().optional(),
});

/**
 * POST /api/bots - Create a new bot
 * 
 * Requires authentication.
 * Creates a new bot linked to the authenticated user's account.
 * 
 * Validates: Requirements 1.1, 1.2
 */
export async function POST(request: Request) {
  try {
    const user = await requireAuth();
    const body = await request.json();
    const data = createBotSchema.parse(body);

    const bot = await createBot(user.id, {
      name: data.name,
      handle: data.handle,
      bio: data.bio,
      avatarUrl: data.avatarUrl,
      headerUrl: data.headerUrl,
      personality: data.personality,
      llmProvider: data.llmProvider,
      llmModel: data.llmModel,
      llmEndpoint: data.llmEndpoint,
      llmApiKey: data.llmApiKey,
      schedule: data.schedule,
      autonomousMode: data.autonomousMode,
    });

    // Return bot without sensitive data
    return NextResponse.json({
      success: true,
      bot: {
        id: bot.id,
        userId: bot.userId,
        name: bot.name,
        handle: bot.handle,
        bio: bot.bio,
        avatarUrl: bot.avatarUrl,
        personalityConfig: bot.personalityConfig,
        llmProvider: bot.llmProvider,
        llmModel: bot.llmModel,
        llmEndpoint: bot.llmEndpoint,
        scheduleConfig: bot.scheduleConfig,
        autonomousMode: bot.autonomousMode,
        isActive: bot.isActive,
        isSuspended: bot.isSuspended,
        lastPostAt: bot.lastPostAt,
        createdAt: bot.createdAt,
        updatedAt: bot.updatedAt,
      },
    }, { status: 201 });
  } catch (error) {
    console.error('Create bot error:', error);

    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { error: 'Invalid input', details: error.issues },
        { status: 400 }
      );
    }

    if (error instanceof Error && error.message === 'Authentication required') {
      return NextResponse.json({ error: 'Authentication required' }, { status: 401 });
    }

    if (error instanceof BotLimitExceededError) {
      return NextResponse.json(
        { error: error.message, code: error.code },
        { status: 403 }
      );
    }

    if (error instanceof BotHandleTakenError) {
      return NextResponse.json(
        { error: error.message, code: error.code },
        { status: 409 }
      );
    }

    if (error instanceof BotValidationError) {
      return NextResponse.json(
        { error: error.message, code: error.code },
        { status: 400 }
      );
    }

    return NextResponse.json(
      { error: 'Failed to create bot' },
      { status: 500 }
    );
  }
}

/**
 * GET /api/bots - List user's bots
 * 
 * Requires authentication.
 * Returns all bots belonging to the authenticated user.
 * 
 * Validates: Requirements 1.3
 */
export async function GET() {
  try {
    const user = await requireAuth();
    const userBots = await getBotsByUser(user.id);

    // Return bots without sensitive data
    const sanitizedBots = userBots.map(bot => ({
      id: bot.id,
      userId: bot.userId,
      name: bot.name,
      handle: bot.handle,
      bio: bot.bio,
      avatarUrl: bot.avatarUrl,
      personalityConfig: bot.personalityConfig,
      llmProvider: bot.llmProvider,
      llmModel: bot.llmModel,
      llmEndpoint: bot.llmEndpoint,
      scheduleConfig: bot.scheduleConfig,
      autonomousMode: bot.autonomousMode,
      isActive: bot.isActive,
      isSuspended: bot.isSuspended,
      suspensionReason: bot.suspensionReason,
      lastPostAt: bot.lastPostAt,
      createdAt: bot.createdAt,
      updatedAt: bot.updatedAt,
    }));

    return NextResponse.json({
      success: true,
      bots: sanitizedBots,
    });
  } catch (error) {
    console.error('List bots error:', error);

    if (error instanceof Error && error.message === 'Authentication required') {
      return NextResponse.json({ error: 'Authentication required' }, { status: 401 });
    }

    return NextResponse.json(
      { error: 'Failed to list bots' },
      { status: 500 }
    );
  }
}
