import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import {
  buildBusinessAudience,
  buildEvbAudience,
  buildOrderAudience,
  isCumasConfigured,
  type AudienceRecipient,
} from '@/lib/crm/cumas-client';
import { withAuth } from '@/core/auth';

export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';

const BusinessServerSchema = z.object({
  firma: z.string().optional(),
  plz: z.string().optional(),
  strasse: z.string().optional(),
  email: z.string().optional(),
  itsAccessId: z.number().int().optional(),
  itsNr: z.number().int().optional(),
  ksmNr: z.number().int().optional(),
  spaNr: z.number().int().optional(),
  idkdnr: z.number().int().optional(),
}).partial();

const BusinessClientSchema = z.object({
  itsKsmIn: z.array(z.string()).optional(),
  ortContains: z.string().optional(),
  brancheContains: z.string().optional(),
  plzPrefix: z.string().max(5).optional(),
  hasEmail: z.boolean().optional(),
  vshvEigen: z.boolean().optional(),
  vshvFremd: z.boolean().optional(),
  resellerIn: z.array(z.string()).optional(),
  briefstatus: z.array(z.string()).optional(),
  kzkStatus: z.array(z.string()).optional(),
  kundengroesse: z.array(z.string()).optional(),
  statusCodes: z.array(z.string()).optional(),
  excludeStatusCodes: z.array(z.string()).optional(),
}).partial();

const EvbServerSchema = z.object({
  evbnr: z.string().optional(),
  rechnr: z.string().optional(),
  idkdnr: z.number().int().optional(),
  itsBusinessData: z.number().int().optional(),
  orderPrivateShop: z.number().int().optional(),
  rechdatumAfter: z.string().optional(),
  rechdatumBefore: z.string().optional(),
}).partial();

const EvbClientSchema = z.object({
  typIn: z.array(z.string()).optional(),
  gesellschaftIn: z.array(z.string()).optional(),
  resellerIn: z.array(z.string()).optional(),
  storno: z.boolean().optional(),
  aktiviert: z.boolean().optional(),
  bezahlt: z.boolean().optional(),
  vkverstMin: z.number().optional(),
  vkverstMax: z.number().optional(),
}).partial();

const OrderServerSchema = z.object({
  invoiceNumber: z.string().optional(),
  email: z.string().optional(),
  clientName: z.string().optional(),
  regDatetimeAfter: z.string().optional(),
  regDatetimeBefore: z.string().optional(),
}).partial();

const OrderClientSchema = z.object({
  productContains: z.string().optional(),
  hasEvbs: z.boolean().optional(),
  totalMin: z.number().optional(),
  totalMax: z.number().optional(),
}).partial();

const RequestSchema = z.discriminatedUnion('source', [
  z.object({
    source: z.literal('business'),
    server: BusinessServerSchema.default({}),
    client: BusinessClientSchema.default({}),
    maxRecords: z.number().int().min(1).max(5000).default(200),
    preview: z.boolean().default(false),
  }),
  z.object({
    source: z.literal('evb'),
    server: EvbServerSchema.default({}),
    client: EvbClientSchema.default({}),
    maxRecords: z.number().int().min(1).max(5000).default(200),
    preview: z.boolean().default(false),
  }),
  z.object({
    source: z.literal('orders'),
    server: OrderServerSchema.default({}),
    client: OrderClientSchema.default({}),
    maxRecords: z.number().int().min(1).max(5000).default(200),
    preview: z.boolean().default(false),
  }),
]);

function stubMockRecipients(source: 'business' | 'orders' | 'evb'): AudienceRecipient[] {
  // Realistische Mocks pro Quelle, damit UI-Tabs auch ohne Live-CRM klar getrennt sind.
  const base: Array<Omit<AudienceRecipient, 'source'>> = [
    { email: 'max.mustermann@its-mock.example', firstName: 'Max', lastName: 'Mustermann', company: 'Mustermann GmbH', cumasId: 1001, rawRecord: { id: 1001, firma: 'Mustermann GmbH', its_ksm: 'ITS', ort: 'München', email: 'max.mustermann@its-mock.example' } },
    { email: 'erika.musterfrau@sits-mock.example', firstName: 'Erika', lastName: 'Musterfrau', company: 'Musterfrau Spedition', cumasId: 1002, rawRecord: { id: 1002, firma: 'Musterfrau Spedition', its_ksm: 'SITS', ort: 'Berlin', email: 'erika.musterfrau@sits-mock.example' } },
    { email: 'klaus.kollege@ksm-mock.example', firstName: 'Klaus', lastName: 'Kollege', company: 'Kollege Auto', cumasId: 1003, rawRecord: { id: 1003, firma: 'Kollege Auto', its_ksm: 'KSM', ort: 'Hamburg', email: 'klaus.kollege@ksm-mock.example' } },
    { email: 'anita.privat@spa-mock.example', firstName: 'Anita', lastName: 'Privat', cumasId: 2001, rawRecord: { id: 2001, client_name: 'Anita Privat', email: 'anita.privat@spa-mock.example', product: 'KZK' } },
    { email: 'bernd.bestand@spa-mock.example', firstName: 'Bernd', lastName: 'Bestand', cumasId: 2002, rawRecord: { id: 2002, client_name: 'Bernd Bestand', email: 'bernd.bestand@spa-mock.example', product: 'KZKA' } },
  ];
  return base.map((r) => ({ ...r, source }));
}

export const POST = withAuth(async (req: NextRequest, _ctx) => {
  try {
    const body = await req.json();
    const parsed = RequestSchema.safeParse(body);
    if (!parsed.success) {
      return NextResponse.json(
        {
          error: 'Invalid input',
          issues: parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`),
        },
        { status: 400 },
      );
    }

    if (!isCumasConfigured()) {
      const mock = stubMockRecipients(parsed.data.source);
      return NextResponse.json({
        ok: true,
        recipients: mock,
        totalScanned: mock.length,
        totalAvailable: mock.length,
        meta: {
          source: 'stub',
          durationMs: 0,
          note: 'CRM_USERNAME / CRM_PASSWORD nicht in .env.local — Stub-Empfänger',
        },
      });
    }

    const start = Date.now();
    const limit = parsed.data.preview ? Math.min(parsed.data.maxRecords, 20) : parsed.data.maxRecords;

    let result;
    if (parsed.data.source === 'business') {
      result = await buildBusinessAudience({
        server: parsed.data.server,
        client: parsed.data.client,
        maxRecords: limit,
      });
    } else if (parsed.data.source === 'evb') {
      result = await buildEvbAudience({
        server: parsed.data.server,
        client: parsed.data.client,
        maxRecords: limit,
      });
    } else {
      result = await buildOrderAudience({
        server: parsed.data.server,
        client: parsed.data.client,
        maxRecords: limit,
      });
    }

    return NextResponse.json({
      ok: true,
      ...result,
      meta: {
        source: 'cumas',
        durationMs: Date.now() - start,
        preview: parsed.data.preview,
        resource: parsed.data.source,
      },
    });
  } catch (err) {
    console.error('[/api/crm/audience] error:', err);
    return NextResponse.json(
      { error: err instanceof Error ? err.message : 'Internal error' },
      { status: 500 },
    );
  }
});
