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 a product
const updateProductSchema = z.object({
  categoryId: z.string().cuid('Invalid category ID').optional(),
  name: z.string().min(1, 'Product name is required').max(100).optional(),
  description: z.string().max(1000).optional().nullable(),
  sku: z.string().max(50).optional().nullable(),
  price: z.number().nonnegative('Price must be non-negative').optional(),
  costPrice: z.number().nonnegative('Cost price must be non-negative').optional().nullable(),
  stock: z.number().int().min(0, 'Stock must be non-negative').optional(),
  minStock: z.number().int().min(0, 'Minimum stock must be non-negative').optional(),
  trackStock: z.boolean().optional(),
  image: z.string().url().optional().nullable(),
  isActive: z.boolean().optional(),
});

// GET /api/products/[id] - Get a single product by ID
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;

    const product = await db.product.findFirst({
      where: {
        id,
        organizationId: session.user.organizationId,
      },
      include: {
        category: {
          select: {
            id: true,
            name: true,
            description: true,
          },
        },
      },
    });

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

    // Add lowStock indicator
    const productWithLowStock = {
      ...product,
      lowStock: product.trackStock && product.stock < product.minStock,
    };

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

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

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

    // Check if user has admin role
    const allowedRoles = ['SUPER_ADMIN', 'ORG_ADMIN', 'SITE_ADMIN'];
    if (!allowedRoles.includes(session.user.role)) {
      return NextResponse.json(
        { error: 'Forbidden: Insufficient permissions' },
        { status: 403 }
      );
    }

    const { id } = await context.params;

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

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

    const body = await request.json();

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

    const {
      categoryId,
      name,
      description,
      sku,
      price,
      costPrice,
      stock,
      minStock,
      trackStock,
      image,
      isActive,
    } = validationResult.data;

    // If categoryId is provided, verify it belongs to user's organization
    if (categoryId) {
      const category = await db.productCategory.findFirst({
        where: {
          id: categoryId,
          organizationId: session.user.organizationId,
        },
      });

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

    // Check if SKU is unique within the organization (if changed)
    if (sku && sku !== existingProduct.sku) {
      const existingWithSku = await db.product.findFirst({
        where: {
          organizationId: session.user.organizationId,
          sku,
          NOT: { id },
        },
      });

      if (existingWithSku) {
        return NextResponse.json(
          { error: 'A product with this SKU already exists' },
          { status: 409 }
        );
      }
    }

    const product = await db.product.update({
      where: { id },
      data: {
        ...(categoryId !== undefined && { categoryId }),
        ...(name !== undefined && { name }),
        ...(description !== undefined && { description }),
        ...(sku !== undefined && { sku }),
        ...(price !== undefined && { price }),
        ...(costPrice !== undefined && { costPrice }),
        ...(stock !== undefined && { stock }),
        ...(minStock !== undefined && { minStock }),
        ...(trackStock !== undefined && { trackStock }),
        ...(image !== undefined && { image }),
        ...(isActive !== undefined && { isActive }),
      },
      include: {
        category: {
          select: {
            id: true,
            name: true,
            description: true,
          },
        },
      },
    });

    // Add lowStock indicator
    const productWithLowStock = {
      ...product,
      lowStock: product.trackStock && product.stock < product.minStock,
    };

    return NextResponse.json(productWithLowStock);
  } catch (error) {
    console.error('Error updating product:', error);
    return NextResponse.json(
      { error: 'Failed to update product' },
      { status: 500 }
    );
  }
}

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

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

    // Check if user has admin role
    const allowedRoles = ['SUPER_ADMIN', 'ORG_ADMIN', 'SITE_ADMIN'];
    if (!allowedRoles.includes(session.user.role)) {
      return NextResponse.json(
        { error: 'Forbidden: Insufficient permissions' },
        { status: 403 }
      );
    }

    const { id } = await context.params;

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

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

    // Soft delete: set isActive to false
    await db.product.update({
      where: { id },
      data: { isActive: false },
    });

    return NextResponse.json(
      { message: 'Product deleted successfully' },
      { status: 200 }
    );
  } catch (error) {
    console.error('Error deleting product:', error);
    return NextResponse.json(
      { error: 'Failed to delete product' },
      { status: 500 }
    );
  }
}
