import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { db } from '@/lib/db';
import { createClientSchema } from '@smashpoint/shared';

// GET /api/clients - List/search clients
export async function GET(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);

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

    const { searchParams } = new URL(request.url);
    const search = searchParams.get('search');
    const isActive = searchParams.get('isActive');
    const limit = searchParams.get('limit');
    const offset = searchParams.get('offset');

    // Build the where clause
    interface ClientWhereClause {
      organizationId: string;
      isActive?: boolean;
      OR?: Array<{
        firstName?: { contains: string; mode: 'insensitive' };
        lastName?: { contains: string; mode: 'insensitive' };
        email?: { contains: string; mode: 'insensitive' };
        phone?: { contains: string; mode: 'insensitive' };
      }>;
    }

    const whereClause: ClientWhereClause = {
      organizationId: session.user.organizationId,
    };

    // Filter by active status
    if (isActive !== null) {
      whereClause.isActive = isActive !== 'false';
    }

    // Search filter for name, email, or phone
    if (search && search.trim().length > 0) {
      const searchTerm = search.trim();
      whereClause.OR = [
        { firstName: { contains: searchTerm, mode: 'insensitive' } },
        { lastName: { contains: searchTerm, mode: 'insensitive' } },
        { email: { contains: searchTerm, mode: 'insensitive' } },
        { phone: { contains: searchTerm, mode: 'insensitive' } },
      ];
    }

    // Build pagination options
    const take = limit ? Math.min(parseInt(limit, 10), 100) : 50;
    const skip = offset ? parseInt(offset, 10) : 0;

    // Get total count for pagination
    const totalCount = await db.client.count({
      where: whereClause,
    });

    const clients = await db.client.findMany({
      where: whereClause,
      select: {
        id: true,
        firstName: true,
        lastName: true,
        email: true,
        phone: true,
        level: true,
        tags: true,
        isActive: true,
        createdAt: true,
        memberships: {
          where: {
            status: 'ACTIVE',
            endDate: {
              gte: new Date(),
            },
          },
          select: {
            id: true,
            status: true,
            remainingHours: true,
            endDate: true,
            plan: {
              select: {
                id: true,
                name: true,
                discountPercent: true,
              },
            },
          },
          take: 1,
        },
        _count: {
          select: {
            bookings: true,
          },
        },
      },
      orderBy: [
        { lastName: 'asc' },
        { firstName: 'asc' },
      ],
      take,
      skip,
    });

    return NextResponse.json({
      data: clients,
      pagination: {
        total: totalCount,
        limit: take,
        offset: skip,
        hasMore: skip + take < totalCount,
      },
    });
  } catch (error) {
    console.error('Error fetching clients:', error);
    return NextResponse.json(
      { error: 'Error al obtener los clientes' },
      { status: 500 }
    );
  }
}

// POST /api/clients - Create a new client
export async function POST(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);

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

    const body = await request.json();

    // Validate input with Zod schema
    const validationResult = createClientSchema.safeParse(body);
    if (!validationResult.success) {
      return NextResponse.json(
        {
          error: 'Datos del cliente inválidos',
          details: validationResult.error.flatten().fieldErrors,
        },
        { status: 400 }
      );
    }

    const {
      firstName,
      lastName,
      email,
      phone,
      dateOfBirth,
      address,
      city,
      postalCode,
      notes,
      tags,
      skillLevel,
      emergencyContact,
    } = validationResult.data;

    // Check if client with same email already exists in organization
    if (email) {
      const existingClient = await db.client.findFirst({
        where: {
          organizationId: session.user.organizationId,
          email,
        },
      });

      if (existingClient) {
        return NextResponse.json(
          { error: 'Ya existe un cliente con este correo electrónico en su organización' },
          { status: 409 }
        );
      }
    }

    // Create the client
    const client = await db.client.create({
      data: {
        organizationId: session.user.organizationId,
        firstName,
        lastName,
        email: email || null,
        phone: phone || null,
        dateOfBirth: dateOfBirth || null,
        address: address || null,
        notes: notes || null,
        tags: tags || [],
        level: skillLevel || null,
        emergencyContact: emergencyContact?.name || null,
        emergencyPhone: emergencyContact?.phone || null,
        isActive: true,
      },
      select: {
        id: true,
        firstName: true,
        lastName: true,
        email: true,
        phone: true,
        level: true,
        tags: true,
        isActive: true,
        createdAt: true,
      },
    });

    return NextResponse.json(client, { status: 201 });
  } catch (error) {
    console.error('Error creating client:', error);

    // Check for unique constraint violation
    if (error instanceof Error && error.message.includes('Unique constraint')) {
      return NextResponse.json(
        { error: 'Ya existe un cliente con este correo electrónico o DNI' },
        { status: 409 }
      );
    }

    return NextResponse.json(
      { error: 'Error al crear el cliente' },
      { status: 500 }
    );
  }
}
