import { NextRequest, NextResponse } from "next/server";
import { Prisma } from "@prisma/client";
import { prisma } from "@/core/storage/prisma";
import { v4 as uuid } from "uuid";

const NAMESPACE = "address-book";
const PREFIX = "contact:";

// ─── Auth: Bearer token OR NextAuth session ─────────────────────────
// External tools use: Authorization: Bearer <ADDRESSBOOK_API_KEY>
// Browser users fall through middleware (NextAuth session)

function checkBearerAuth(req: NextRequest): boolean {
  const secret = process.env.ADDRESSBOOK_API_KEY;
  if (!secret) return false;
  const authHeader = req.headers.get("Authorization");
  const token = authHeader?.replace("Bearer ", "");
  return token === secret;
}

// ─── GET /api/address-book ──────────────────────────────────────────
// Query params:
//   ?id=<uuid>          → single contact
//   ?q=<search>         → search by name/company/email/phone
//   ?type=<ContactType> → filter by type
//   (no params)         → all contacts

export async function GET(req: NextRequest) {
  if (!checkBearerAuth(req)) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const params = req.nextUrl.searchParams;
  const id = params.get("id");
  const q = params.get("q")?.toLowerCase();
  const type = params.get("type");

  try {
    // Single contact by ID
    if (id) {
      const item = await prisma.keyValueStore.findUnique({
        where: { namespace_key: { namespace: NAMESPACE, key: `${PREFIX}${id}` } },
      });
      if (!item) {
        return NextResponse.json({ error: "Contact not found" }, { status: 404 });
      }
      return NextResponse.json({ contact: item.value });
    }

    // All contacts (with optional filtering)
    const items = await prisma.keyValueStore.findMany({
      where: { namespace: NAMESPACE },
      select: { key: true, value: true },
    });

    let contacts: Record<string, unknown>[] = [];
    for (const item of items) {
      if (!item.key.startsWith(PREFIX)) continue;
      const val = item.value as Record<string, unknown>;
      if (!val) continue;

      // Type filter
      if (type && val.type !== type) continue;

      // Search filter
      if (q) {
        const name = String(val.name ?? "").toLowerCase();
        const company = String(val.company ?? "").toLowerCase();
        const email = String(val.email ?? "").toLowerCase();
        const phone = String(val.phone ?? "");
        if (
          !name.includes(q) &&
          !company.includes(q) &&
          !email.includes(q) &&
          !phone.includes(q)
        ) continue;
      }

      contacts.push(val);
    }

    // Sort by name/company
    contacts.sort((a, b) => {
      const aLabel = String(a.name || a.company || "");
      const bLabel = String(b.name || b.company || "");
      return aLabel.localeCompare(bLabel, "ro");
    });

    return NextResponse.json({ contacts, total: contacts.length });
  } catch (error) {
    console.error("Address book GET error:", error);
    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}

// ─── POST /api/address-book ─────────────────────────────────────────
// Body: { name?, company?, type?, email?, phone?, ... }
// Returns: { contact: AddressContact }
// Validation: at least name OR company required

export async function POST(req: NextRequest) {
  if (!checkBearerAuth(req)) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = await req.json();

    const name = String(body.name ?? "").trim();
    const company = String(body.company ?? "").trim();

    if (!name && !company) {
      return NextResponse.json(
        { error: "Cel puțin name sau company este obligatoriu" },
        { status: 400 },
      );
    }

    // Auto-detect type: if only company → institution
    const autoType = !name && company ? "institution" : "client";

    const now = new Date().toISOString();
    const id = body.id ?? uuid();

    const contact = {
      id,
      name,
      company,
      type: body.type ?? autoType,
      email: String(body.email ?? "").trim(),
      email2: String(body.email2 ?? "").trim(),
      phone: String(body.phone ?? "").trim(),
      phone2: String(body.phone2 ?? "").trim(),
      address: String(body.address ?? "").trim(),
      department: String(body.department ?? "").trim(),
      role: String(body.role ?? "").trim(),
      website: String(body.website ?? "").trim(),
      projectIds: Array.isArray(body.projectIds) ? body.projectIds : [],
      contactPersons: Array.isArray(body.contactPersons) ? body.contactPersons : [],
      tags: Array.isArray(body.tags) ? body.tags : [],
      notes: String(body.notes ?? "").trim(),
      visibility: body.visibility ?? "company",
      createdAt: now,
      updatedAt: now,
    };

    await prisma.keyValueStore.upsert({
      where: { namespace_key: { namespace: NAMESPACE, key: `${PREFIX}${id}` } },
      update: { value: contact as unknown as Prisma.InputJsonValue },
      create: { namespace: NAMESPACE, key: `${PREFIX}${id}`, value: contact as unknown as Prisma.InputJsonValue },
    });

    return NextResponse.json({ contact }, { status: 201 });
  } catch (error) {
    console.error("Address book POST error:", error);
    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}

// ─── PUT /api/address-book ──────────────────────────────────────────
// Body: { id: "<uuid>", ...fields to update }
// Merges with existing contact, updates updatedAt

export async function PUT(req: NextRequest) {
  if (!checkBearerAuth(req)) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = await req.json();
    const id = body.id;

    if (!id) {
      return NextResponse.json({ error: "id is required" }, { status: 400 });
    }

    const existing = await prisma.keyValueStore.findUnique({
      where: { namespace_key: { namespace: NAMESPACE, key: `${PREFIX}${id}` } },
    });

    if (!existing) {
      return NextResponse.json({ error: "Contact not found" }, { status: 404 });
    }

    const prev = existing.value as Record<string, unknown>;
    const updated = {
      ...prev,
      ...body,
      id: prev.id, // never overwrite
      createdAt: prev.createdAt, // never overwrite
      updatedAt: new Date().toISOString(),
    };

    // Re-validate: name OR company
    if (!String(updated.name ?? "").trim() && !String(updated.company ?? "").trim()) {
      return NextResponse.json(
        { error: "Cel puțin name sau company este obligatoriu" },
        { status: 400 },
      );
    }

    await prisma.keyValueStore.update({
      where: { namespace_key: { namespace: NAMESPACE, key: `${PREFIX}${id}` } },
      data: { value: updated as unknown as Prisma.InputJsonValue },
    });

    return NextResponse.json({ contact: updated });
  } catch (error) {
    console.error("Address book PUT error:", error);
    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}

// ─── DELETE /api/address-book?id=<uuid> ─────────────────────────────

export async function DELETE(req: NextRequest) {
  if (!checkBearerAuth(req)) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const id = req.nextUrl.searchParams.get("id");
  if (!id) {
    return NextResponse.json({ error: "id is required" }, { status: 400 });
  }

  try {
    await prisma.keyValueStore.delete({
      where: { namespace_key: { namespace: NAMESPACE, key: `${PREFIX}${id}` } },
    }).catch(() => { /* ignore if not found */ });

    return NextResponse.json({ success: true });
  } catch (error) {
    console.error("Address book DELETE error:", error);
    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}
