import { NextResponse } from 'next/server';
import { eq } from 'drizzle-orm';

import { withAuth, type AuthContext } from '@/lib/api/helpers';
import { parseBody } from '@/lib/api/route-helpers';
import { db } from '@/lib/db';
import { userProfiles } from '@/lib/db/schema';
import { errorResponse } from '@/lib/errors';
import { z } from 'zod';

const updateProfileSchema = z.object({
  displayName: z.string().min(1).max(200).optional(),
  phone: z.string().nullable().optional(),
  avatarUrl: z.string().url().nullable().optional(),
  preferences: z
    .object({
      dark_mode: z.boolean().optional(),
      locale: z.string().optional(),
      timezone: z.string().optional(),
    })
    .passthrough()
    .optional(),
});

export const GET = withAuth(async (_req, ctx: AuthContext) => {
  return NextResponse.json({
    data: {
      userId: ctx.userId,
      portId: ctx.portId,
      portSlug: ctx.portSlug,
      permissions: ctx.permissions,
      isSuperAdmin: ctx.isSuperAdmin,
      user: ctx.user,
    },
  });
});

export const PATCH = withAuth(async (req, ctx: AuthContext) => {
  try {
    const body = await parseBody(req, updateProfileSchema);

    const profile = await db.query.userProfiles.findFirst({
      where: eq(userProfiles.userId, ctx.userId),
    });
    if (!profile) {
      return NextResponse.json({ error: 'Profile not found' }, { status: 404 });
    }

    const updates: Record<string, unknown> = { updatedAt: new Date() };
    if (body.displayName !== undefined) updates.displayName = body.displayName;
    if (body.phone !== undefined) updates.phone = body.phone;
    if (body.avatarUrl !== undefined) updates.avatarUrl = body.avatarUrl;
    if (body.preferences !== undefined) {
      updates.preferences = {
        ...((profile.preferences as Record<string, unknown>) ?? {}),
        ...body.preferences,
      };
    }

    const [updated] = await db
      .update(userProfiles)
      .set(updates)
      .where(eq(userProfiles.userId, ctx.userId))
      .returning();

    return NextResponse.json({
      data: {
        userId: updated!.userId,
        displayName: updated!.displayName,
        phone: updated!.phone,
        avatarUrl: updated!.avatarUrl,
        preferences: updated!.preferences,
      },
    });
  } catch (error) {
    return errorResponse(error);
  }
});
