import { Response } from 'express';
import { ApiResponse, AuthRequest } from '../types/index.js';
import { logChange } from '../services/audit.service.js';
import * as referralService from '../services/customerReferral.service.js';

// Der ganze Bereich ist rein für Mitarbeiter/Admins – Portal-Kunden dürfen
// Werbe-Beziehungen weder sehen noch ändern. Defense-in-Depth: nicht nur die
// UI blendet den Tab aus, der Endpoint blockt Portal-Token explizit.
function blockPortal(req: AuthRequest, res: Response): boolean {
  if (req.user?.isCustomerPortal) {
    res.status(403).json({ success: false, error: 'Kein Zugriff' } as ApiResponse);
    return true;
  }
  return false;
}

export async function getReferrals(req: AuthRequest, res: Response): Promise<void> {
  try {
    if (blockPortal(req, res)) return;
    const customerId = parseInt(req.params.customerId);
    if (Number.isNaN(customerId)) {
      res.status(400).json({ success: false, error: 'Ungültige Kunden-ID' } as ApiResponse);
      return;
    }
    const data = await referralService.getReferralsForCustomer(customerId);
    res.json({ success: true, data } as ApiResponse);
  } catch (error) {
    res.status(500).json({ success: false, error: 'Fehler beim Laden der Werbe-Beziehungen' } as ApiResponse);
  }
}

export async function searchCustomers(req: AuthRequest, res: Response): Promise<void> {
  try {
    if (blockPortal(req, res)) return;
    const customerId = parseInt(req.params.customerId);
    if (Number.isNaN(customerId)) {
      res.status(400).json({ success: false, error: 'Ungültige Kunden-ID' } as ApiResponse);
      return;
    }
    const search = req.query.search;
    if (!search || typeof search !== 'string' || search.trim().length < 2) {
      res.json({ success: true, data: [] } as ApiResponse);
      return;
    }
    const customers = await referralService.searchCustomersForReferral(search.trim(), customerId);
    res.json({ success: true, data: customers } as ApiResponse);
  } catch (error) {
    res.status(500).json({ success: false, error: 'Fehler bei der Suche' } as ApiResponse);
  }
}

export async function createReferral(req: AuthRequest, res: Response): Promise<void> {
  try {
    if (blockPortal(req, res)) return;
    const customerId = parseInt(req.params.customerId);
    if (Number.isNaN(customerId)) {
      res.status(400).json({ success: false, error: 'Ungültige Kunden-ID' } as ApiResponse);
      return;
    }
    const { direction, otherCustomerId, relationship } = req.body ?? {};
    const otherId = parseInt(otherCustomerId);
    if (Number.isNaN(otherId)) {
      res.status(400).json({ success: false, error: 'Kein Kunde ausgewählt' } as ApiResponse);
      return;
    }

    // direction bestimmt, wer Werber und wer Geworbener ist:
    //  'recruitedBy' = dieser Kunde wurde vom anderen geworben (Abschnitt 1)
    //  'recruited'   = dieser Kunde hat den anderen geworben  (Abschnitt 2)
    let recruiterId: number;
    let recruitedId: number;
    if (direction === 'recruitedBy') {
      recruiterId = otherId;
      recruitedId = customerId;
    } else if (direction === 'recruited') {
      recruiterId = customerId;
      recruitedId = otherId;
    } else {
      res.status(400).json({ success: false, error: 'Ungültige Richtung' } as ApiResponse);
      return;
    }

    const created = await referralService.createReferral({
      recruiterId,
      recruitedId,
      relationship: (relationship ?? '').toString(),
      createdBy: req.user?.email,
    });

    await logChange({
      req,
      action: 'CREATE',
      resourceType: 'CustomerReferral',
      resourceId: created.id.toString(),
      label: `Werbe-Beziehung angelegt: Kunde #${recruiterId} hat Kunde #${recruitedId} geworben (${created.relationship})`,
      customerId: recruitedId,
    });

    res.status(201).json({ success: true, data: created } as ApiResponse);
  } catch (error) {
    const status = (error as referralService.ReferralError)?.status ?? 500;
    res.status(status).json({
      success: false,
      error: error instanceof Error ? error.message : 'Fehler beim Anlegen der Werbe-Beziehung',
    } as ApiResponse);
  }
}

export async function updateReferral(req: AuthRequest, res: Response): Promise<void> {
  try {
    if (blockPortal(req, res)) return;
    const customerId = parseInt(req.params.customerId);
    const referralId = parseInt(req.params.referralId);
    if (Number.isNaN(customerId) || Number.isNaN(referralId)) {
      res.status(400).json({ success: false, error: 'Ungültige ID' } as ApiResponse);
      return;
    }
    const { direction, otherCustomerId, relationship } = req.body ?? {};
    const otherId = parseInt(otherCustomerId);
    if (Number.isNaN(otherId)) {
      res.status(400).json({ success: false, error: 'Kein Kunde ausgewählt' } as ApiResponse);
      return;
    }

    let recruiterId: number;
    let recruitedId: number;
    if (direction === 'recruitedBy') {
      recruiterId = otherId;
      recruitedId = customerId;
    } else if (direction === 'recruited') {
      recruiterId = customerId;
      recruitedId = otherId;
    } else {
      res.status(400).json({ success: false, error: 'Ungültige Richtung' } as ApiResponse);
      return;
    }

    const updated = await referralService.updateReferral({
      id: referralId,
      recruiterId,
      recruitedId,
      relationship: (relationship ?? '').toString(),
    });

    await logChange({
      req,
      action: 'UPDATE',
      resourceType: 'CustomerReferral',
      resourceId: updated.id.toString(),
      label: `Werbe-Beziehung geändert: Kunde #${recruiterId} hat Kunde #${recruitedId} geworben (${updated.relationship})`,
      customerId: recruitedId,
    });

    res.json({ success: true, data: updated } as ApiResponse);
  } catch (error) {
    const status = (error as referralService.ReferralError)?.status ?? 500;
    res.status(status).json({
      success: false,
      error: error instanceof Error ? error.message : 'Fehler beim Ändern der Werbe-Beziehung',
    } as ApiResponse);
  }
}

export async function deleteReferral(req: AuthRequest, res: Response): Promise<void> {
  try {
    if (blockPortal(req, res)) return;
    const referralId = parseInt(req.params.referralId);
    if (Number.isNaN(referralId)) {
      res.status(400).json({ success: false, error: 'Ungültige ID' } as ApiResponse);
      return;
    }
    const ok = await referralService.deleteReferral(referralId);
    if (!ok) {
      res.status(404).json({ success: false, error: 'Eintrag nicht gefunden' } as ApiResponse);
      return;
    }
    await logChange({
      req,
      action: 'DELETE',
      resourceType: 'CustomerReferral',
      resourceId: referralId.toString(),
      label: `Werbe-Beziehung #${referralId} entfernt`,
    });
    res.json({ success: true } as ApiResponse);
  } catch (error) {
    res.status(500).json({ success: false, error: 'Fehler beim Entfernen der Werbe-Beziehung' } as ApiResponse);
  }
}
