import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import { prisma } from "@/lib/prisma";
import { encrypt } from "@/lib/crypto";
import { geocodeAddress } from "@/lib/geocode";

export async function GET() {
  const settings = await prisma.settings.findUnique({ where: { id: "singleton" } });
  return NextResponse.json({
    notificationEmail: settings?.notificationEmail ?? "",
    stripePublishableKey: settings?.stripePublishableKey ?? "",
    stripeSecretKeyConfigured: Boolean(settings?.stripeSecretKeyEnc),
    stripeWebhookSecretConfigured: Boolean(settings?.stripeWebhookSecretEnc),
    galleryLayout: settings?.galleryLayout ?? "square",
    businessAddress: settings?.businessAddress ?? "",
    businessPhone: settings?.businessPhone ?? "",
    businessHours: settings?.businessHours ?? "",
    businessLat: settings?.businessLat ?? null,
    businessLng: settings?.businessLng ?? null,
    instagramEnabled: settings?.instagramEnabled ?? false,
    instagramUrl: settings?.instagramUrl ?? "",
    facebookEnabled: settings?.facebookEnabled ?? false,
    facebookUrl: settings?.facebookUrl ?? "",
    tiktokEnabled: settings?.tiktokEnabled ?? false,
    tiktokUrl: settings?.tiktokUrl ?? "",
    youtubeEnabled: settings?.youtubeEnabled ?? false,
    youtubeUrl: settings?.youtubeUrl ?? "",
  });
}

const settingsSchema = z.object({
  notificationEmail: z.email().or(z.literal("")).optional(),
  stripePublishableKey: z.string().optional(),
  stripeSecretKey: z.string().optional(),
  stripeWebhookSecret: z.string().optional(),
  galleryLayout: z.enum(["square", "landscape", "portrait"]).optional(),
  businessAddress: z.string().max(500).optional(),
  businessPhone: z.string().max(50).optional(),
  businessHours: z.string().max(500).optional(),
  instagramEnabled: z.boolean().optional(),
  instagramUrl: z.string().max(500).optional(),
  facebookEnabled: z.boolean().optional(),
  facebookUrl: z.string().max(500).optional(),
  tiktokEnabled: z.boolean().optional(),
  tiktokUrl: z.string().max(500).optional(),
  youtubeEnabled: z.boolean().optional(),
  youtubeUrl: z.string().max(500).optional(),
});

function normalizeUrl(url: string) {
  const trimmed = url.trim();
  if (!trimmed) return "";
  return /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
}

export async function PUT(request: NextRequest) {
  const body = await request.json().catch(() => null);
  const parsed = settingsSchema.safeParse(body);
  if (!parsed.success) {
    return NextResponse.json({ error: "Invalid settings" }, { status: 400 });
  }
  const {
    notificationEmail,
    stripePublishableKey,
    stripeSecretKey,
    stripeWebhookSecret,
    galleryLayout,
    businessAddress,
    businessPhone,
    businessHours,
    instagramEnabled,
    instagramUrl,
    facebookEnabled,
    facebookUrl,
    tiktokEnabled,
    tiktokUrl,
    youtubeEnabled,
    youtubeUrl,
  } = parsed.data;

  const data: {
    notificationEmail?: string;
    stripePublishableKey?: string;
    stripeSecretKeyEnc?: string;
    stripeWebhookSecretEnc?: string;
    galleryLayout?: string;
    businessAddress?: string;
    businessPhone?: string;
    businessHours?: string;
    businessLat?: number | null;
    businessLng?: number | null;
    instagramEnabled?: boolean;
    instagramUrl?: string;
    facebookEnabled?: boolean;
    facebookUrl?: string;
    tiktokEnabled?: boolean;
    tiktokUrl?: string;
    youtubeEnabled?: boolean;
    youtubeUrl?: string;
  } = {};

  if (notificationEmail !== undefined) data.notificationEmail = notificationEmail;
  if (stripePublishableKey !== undefined) data.stripePublishableKey = stripePublishableKey;
  if (stripeSecretKey) data.stripeSecretKeyEnc = encrypt(stripeSecretKey);
  if (stripeWebhookSecret) data.stripeWebhookSecretEnc = encrypt(stripeWebhookSecret);
  if (galleryLayout !== undefined) data.galleryLayout = galleryLayout;
  if (businessPhone !== undefined) data.businessPhone = businessPhone;
  if (businessHours !== undefined) data.businessHours = businessHours;
  if (instagramEnabled !== undefined) data.instagramEnabled = instagramEnabled;
  if (instagramUrl !== undefined) data.instagramUrl = normalizeUrl(instagramUrl);
  if (facebookEnabled !== undefined) data.facebookEnabled = facebookEnabled;
  if (facebookUrl !== undefined) data.facebookUrl = normalizeUrl(facebookUrl);
  if (tiktokEnabled !== undefined) data.tiktokEnabled = tiktokEnabled;
  if (tiktokUrl !== undefined) data.tiktokUrl = normalizeUrl(tiktokUrl);
  if (youtubeEnabled !== undefined) data.youtubeEnabled = youtubeEnabled;
  if (youtubeUrl !== undefined) data.youtubeUrl = normalizeUrl(youtubeUrl);

  if (businessAddress !== undefined) {
    data.businessAddress = businessAddress;

    const existing = await prisma.settings.findUnique({ where: { id: "singleton" } });
    if (businessAddress.trim() !== (existing?.businessAddress ?? "").trim()) {
      // Address changed (or was cleared) — re-geocode via free OSM Nominatim
      // so the map on /contact can find new coordinates without needing a
      // paid/keyed Google Maps API.
      const coords = await geocodeAddress(businessAddress);
      data.businessLat = coords?.lat ?? null;
      data.businessLng = coords?.lng ?? null;
    }
  }

  await prisma.settings.upsert({
    where: { id: "singleton" },
    update: data,
    create: { id: "singleton", ...data },
  });

  return NextResponse.json({ success: true });
}
