import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { db } from '@/lib/db';
import { z } from 'zod';

interface RouteContext {
  params: Promise<{ id: string }>;
}

// Validation schema for creating an inscription
const createInscriptionSchema = z.object({
  player1Id: z.string().cuid('Invalid player 1 ID'),
  player2Id: z.string().cuid('Invalid player 2 ID').optional(),
  teamName: z.string().max(100).optional(),
});

// GET /api/tournaments/[id]/inscriptions - List inscriptions for tournament
export async function GET(
  request: NextRequest,
  context: RouteContext
) {
  try {
    const session = await getServerSession(authOptions);

    if (!session?.user) {
      return NextResponse.json(
        { error: 'Unauthorized' },
        { status: 401 }
      );
    }

    const { id } = await context.params;

    // Verify tournament exists and belongs to user's organization
    const tournament = await db.tournament.findFirst({
      where: {
        id,
        organizationId: session.user.organizationId,
      },
    });

    if (!tournament) {
      return NextResponse.json(
        { error: 'Tournament not found' },
        { status: 404 }
      );
    }

    const inscriptions = await db.tournamentInscription.findMany({
      where: {
        tournamentId: id,
      },
      include: {
        client: {
          select: {
            id: true,
            firstName: true,
            lastName: true,
            email: true,
            phone: true,
            level: true,
          },
        },
      },
      orderBy: {
        registeredAt: 'asc',
      },
    });

    // Enrich inscriptions with partner info if partnerId exists
    const enrichedInscriptions = await Promise.all(
      inscriptions.map(async (inscription) => {
        let partner = null;
        if (inscription.partnerId) {
          partner = await db.client.findUnique({
            where: { id: inscription.partnerId },
            select: {
              id: true,
              firstName: true,
              lastName: true,
              email: true,
              phone: true,
              level: true,
            },
          });
        }
        return {
          ...inscription,
          partner,
        };
      })
    );

    return NextResponse.json(enrichedInscriptions);
  } catch (error) {
    console.error('Error fetching inscriptions:', error);
    return NextResponse.json(
      { error: 'Failed to fetch inscriptions' },
      { status: 500 }
    );
  }
}

// POST /api/tournaments/[id]/inscriptions - Register team/player
export async function POST(
  request: NextRequest,
  context: RouteContext
) {
  try {
    const session = await getServerSession(authOptions);

    if (!session?.user) {
      return NextResponse.json(
        { error: 'Unauthorized' },
        { status: 401 }
      );
    }

    const { id } = await context.params;

    // Verify tournament exists and belongs to user's organization
    const tournament = await db.tournament.findFirst({
      where: {
        id,
        organizationId: session.user.organizationId,
      },
      include: {
        _count: {
          select: {
            inscriptions: true,
          },
        },
      },
    });

    if (!tournament) {
      return NextResponse.json(
        { error: 'Tournament not found' },
        { status: 404 }
      );
    }

    // Check tournament status is OPEN (REGISTRATION_OPEN)
    if (tournament.status !== 'REGISTRATION_OPEN') {
      return NextResponse.json(
        { error: 'Tournament is not open for registration' },
        { status: 400 }
      );
    }

    // Check maxTeams not exceeded
    if (tournament.maxPlayers && tournament._count.inscriptions >= tournament.maxPlayers) {
      return NextResponse.json(
        { error: 'Tournament has reached maximum number of teams' },
        { status: 400 }
      );
    }

    const body = await request.json();

    // Validate input
    const validationResult = createInscriptionSchema.safeParse(body);
    if (!validationResult.success) {
      return NextResponse.json(
        {
          error: 'Invalid inscription data',
          details: validationResult.error.flatten().fieldErrors,
        },
        { status: 400 }
      );
    }

    const { player1Id, player2Id, teamName } = validationResult.data;

    // Verify player 1 exists and belongs to user's organization
    const player1 = await db.client.findFirst({
      where: {
        id: player1Id,
        organizationId: session.user.organizationId,
      },
    });

    if (!player1) {
      return NextResponse.json(
        { error: 'Player 1 not found or does not belong to your organization' },
        { status: 404 }
      );
    }

    // Check player 1 is not already registered
    const existingInscription = await db.tournamentInscription.findFirst({
      where: {
        tournamentId: id,
        OR: [
          { clientId: player1Id },
          { partnerId: player1Id },
        ],
      },
    });

    if (existingInscription) {
      return NextResponse.json(
        { error: 'Player 1 is already registered for this tournament' },
        { status: 400 }
      );
    }

    // Verify player 2 if provided
    if (player2Id) {
      const player2 = await db.client.findFirst({
        where: {
          id: player2Id,
          organizationId: session.user.organizationId,
        },
      });

      if (!player2) {
        return NextResponse.json(
          { error: 'Player 2 not found or does not belong to your organization' },
          { status: 404 }
        );
      }

      // Check player 2 is not already registered
      const existingInscription2 = await db.tournamentInscription.findFirst({
        where: {
          tournamentId: id,
          OR: [
            { clientId: player2Id },
            { partnerId: player2Id },
          ],
        },
      });

      if (existingInscription2) {
        return NextResponse.json(
          { error: 'Player 2 is already registered for this tournament' },
          { status: 400 }
        );
      }
    }

    // Create inscription
    const inscription = await db.tournamentInscription.create({
      data: {
        tournamentId: id,
        clientId: player1Id,
        partnerId: player2Id || null,
        teamName: teamName || null,
        seedNumber: tournament._count.inscriptions + 1,
        isPaid: false,
        paidAmount: 0,
      },
      include: {
        client: {
          select: {
            id: true,
            firstName: true,
            lastName: true,
            email: true,
            phone: true,
            level: true,
          },
        },
      },
    });

    // Get partner info if exists
    let partner = null;
    if (player2Id) {
      partner = await db.client.findUnique({
        where: { id: player2Id },
        select: {
          id: true,
          firstName: true,
          lastName: true,
          email: true,
          phone: true,
          level: true,
        },
      });
    }

    return NextResponse.json(
      {
        ...inscription,
        partner,
      },
      { status: 201 }
    );
  } catch (error) {
    console.error('Error creating inscription:', error);
    return NextResponse.json(
      { error: 'Failed to create inscription' },
      { status: 500 }
    );
  }
}
