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 updating client
const updateClientSchema = z.object({
  firstName: z.string().min(1, 'El nombre es requerido').optional(),
  lastName: z.string().min(1, 'El apellido es requerido').optional(),
  email: z.string().email('Email invalido').nullable().optional(),
  phone: z.string().nullable().optional(),
  avatar: z.string().url('URL invalida').nullable().optional(),
  dateOfBirth: z.string().nullable().optional(),
  address: z.string().nullable().optional(),
  notes: z.string().nullable().optional(),
  level: z.string().nullable().optional(),
  tags: z.array(z.string()).optional(),
});

// GET /api/clients/[id] - Get a single client with details
export async function GET(
  request: NextRequest,
  context: RouteContext
) {
  try {
    const session = await getServerSession(authOptions);

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

    const { id } = await context.params;

    const client = await db.client.findFirst({
      where: {
        id,
        organizationId: session.user.organizationId,
      },
      include: {
        memberships: {
          where: {
            status: 'ACTIVE',
            endDate: {
              gte: new Date(),
            },
          },
          include: {
            plan: {
              select: {
                id: true,
                name: true,
                price: true,
                durationMonths: true,
                courtHours: true,
                discountPercent: true,
              },
            },
          },
          orderBy: {
            endDate: 'desc',
          },
          take: 1,
        },
        _count: {
          select: {
            bookings: true,
          },
        },
      },
    });

    if (!client) {
      return NextResponse.json(
        { error: 'Cliente no encontrado' },
        { status: 404 }
      );
    }

    // Calculate total spent from payments
    const totalSpentResult = await db.payment.aggregate({
      where: {
        clientId: client.id,
      },
      _sum: {
        amount: true,
      },
    });

    // Calculate total from sales
    const totalSalesResult = await db.sale.aggregate({
      where: {
        clientId: client.id,
      },
      _sum: {
        total: true,
      },
    });

    const totalSpent =
      Number(totalSpentResult._sum.amount || 0) +
      Number(totalSalesResult._sum.total || 0);

    // For now, balance is set to 0 (can be extended with a balance field in the future)
    const balance = 0;

    return NextResponse.json({
      ...client,
      stats: {
        totalBookings: client._count.bookings,
        totalSpent,
        balance,
      },
    });
  } catch (error) {
    console.error('Error fetching client:', error);
    return NextResponse.json(
      { error: 'Error al obtener el cliente' },
      { status: 500 }
    );
  }
}

// PUT /api/clients/[id] - Update a client
export async function PUT(
  request: NextRequest,
  context: RouteContext
) {
  try {
    const session = await getServerSession(authOptions);

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

    const { id } = await context.params;

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

    if (!existingClient) {
      return NextResponse.json(
        { error: 'Cliente no encontrado' },
        { status: 404 }
      );
    }

    const body = await request.json();

    // Validate input
    const validationResult = updateClientSchema.safeParse(body);
    if (!validationResult.success) {
      return NextResponse.json(
        {
          error: 'Datos de actualizacion invalidos',
          details: validationResult.error.flatten().fieldErrors,
        },
        { status: 400 }
      );
    }

    const {
      firstName,
      lastName,
      email,
      phone,
      avatar,
      dateOfBirth,
      address,
      notes,
      level,
      tags,
    } = validationResult.data;

    // Check for email uniqueness if email is being changed
    if (email && email !== existingClient.email) {
      const emailExists = await db.client.findFirst({
        where: {
          organizationId: session.user.organizationId,
          email,
          id: {
            not: id,
          },
        },
      });

      if (emailExists) {
        return NextResponse.json(
          { error: 'Ya existe un cliente con este email' },
          { status: 409 }
        );
      }
    }

    // Build update data
    const updateData: Record<string, unknown> = {};

    if (firstName !== undefined) updateData.firstName = firstName;
    if (lastName !== undefined) updateData.lastName = lastName;
    if (email !== undefined) updateData.email = email;
    if (phone !== undefined) updateData.phone = phone;
    if (avatar !== undefined) updateData.avatar = avatar;
    if (dateOfBirth !== undefined) {
      updateData.dateOfBirth = dateOfBirth ? new Date(dateOfBirth) : null;
    }
    if (address !== undefined) updateData.address = address;
    if (notes !== undefined) updateData.notes = notes;
    if (level !== undefined) updateData.level = level;
    if (tags !== undefined) updateData.tags = tags;

    const client = await db.client.update({
      where: { id },
      data: updateData,
      include: {
        memberships: {
          where: {
            status: 'ACTIVE',
            endDate: {
              gte: new Date(),
            },
          },
          include: {
            plan: {
              select: {
                id: true,
                name: true,
                price: true,
                durationMonths: true,
                courtHours: true,
              },
            },
          },
          take: 1,
        },
        _count: {
          select: {
            bookings: true,
          },
        },
      },
    });

    return NextResponse.json(client);
  } catch (error) {
    console.error('Error updating 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 email o DNI' },
        { status: 409 }
      );
    }

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

// DELETE /api/clients/[id] - Soft delete a client (set isActive = false)
export async function DELETE(
  request: NextRequest,
  context: RouteContext
) {
  try {
    const session = await getServerSession(authOptions);

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

    const { id } = await context.params;

    // Verify client exists and belongs to user's organization
    const existingClient = await db.client.findFirst({
      where: {
        id,
        organizationId: session.user.organizationId,
      },
      include: {
        memberships: {
          where: {
            status: 'ACTIVE',
          },
        },
        bookings: {
          where: {
            status: {
              in: ['PENDING', 'CONFIRMED'],
            },
            startTime: {
              gte: new Date(),
            },
          },
        },
      },
    });

    if (!existingClient) {
      return NextResponse.json(
        { error: 'Cliente no encontrado' },
        { status: 404 }
      );
    }

    // Check for active memberships
    if (existingClient.memberships.length > 0) {
      return NextResponse.json(
        {
          error: 'No se puede desactivar un cliente con membresia activa',
          details: {
            activeMemberships: existingClient.memberships.length,
          },
        },
        { status: 400 }
      );
    }

    // Check for pending/future bookings
    if (existingClient.bookings.length > 0) {
      return NextResponse.json(
        {
          error: 'No se puede desactivar un cliente con reservas pendientes',
          details: {
            pendingBookings: existingClient.bookings.length,
          },
        },
        { status: 400 }
      );
    }

    // Soft delete by setting isActive to false
    const client = await db.client.update({
      where: { id },
      data: {
        isActive: false,
      },
      select: {
        id: true,
        firstName: true,
        lastName: true,
        isActive: true,
      },
    });

    return NextResponse.json({
      message: 'Cliente desactivado exitosamente',
      client,
    });
  } catch (error) {
    console.error('Error deleting client:', error);
    return NextResponse.json(
      { error: 'Error al desactivar el cliente' },
      { status: 500 }
    );
  }
}
