import { Response } from 'express';
import { AuthRequest } from '../types/index.js';
import * as pdfTemplateService from '../services/pdfTemplate.service.js';
import { logChange } from '../services/audit.service.js';
import { canAccessContract } from '../utils/accessControl.js';

export async function getTemplates(req: AuthRequest, res: Response) {
  try {
    const templates = await pdfTemplateService.getAllTemplates();
    res.json({ success: true, data: templates });
  } catch (error) {
    res.status(500).json({ success: false, error: 'Fehler beim Laden' });
  }
}

export async function getTemplate(req: AuthRequest, res: Response) {
  try {
    const template = await pdfTemplateService.getTemplateById(parseInt(req.params.id));
    if (!template) return res.status(404).json({ success: false, error: 'Vorlage nicht gefunden' });
    res.json({ success: true, data: template });
  } catch (error) {
    res.status(500).json({ success: false, error: 'Fehler beim Laden' });
  }
}

export async function createTemplate(req: AuthRequest, res: Response) {
  try {
    if (!req.file) return res.status(400).json({ success: false, error: 'PDF-Datei erforderlich' });

    const { name, description, providerName, phoneFieldPrefix, maxPhoneFields } = req.body;
    const templatePath = `/uploads/pdf-templates/${req.file.filename}`;

    // PDF-Felder auslesen
    let pdfFields: { name: string; type: string; page: number; y: number }[] = [];
    try {
      const extracted = await pdfTemplateService.extractPdfFields(templatePath);
      pdfFields = extracted.fields;
    } catch {
      // PDF hat keine Formularfelder - OK, kann trotzdem gespeichert werden
    }

    const template = await pdfTemplateService.createTemplate({
      name,
      description,
      providerName,
      templatePath,
      originalName: req.file.originalname,
      phoneFieldPrefix,
      maxPhoneFields: maxPhoneFields ? parseInt(maxPhoneFields) : undefined,
    });

    await logChange({
      req, action: 'CREATE', resourceType: 'PdfTemplate',
      resourceId: template.id.toString(),
      label: `Auftragsvorlage "${name}" angelegt`,
    });

    res.status(201).json({ success: true, data: { ...template, pdfFields } });
  } catch (error) {
    res.status(400).json({
      success: false,
      error: error instanceof Error ? error.message : 'Fehler beim Erstellen',
    });
  }
}

export async function updateTemplate(req: AuthRequest, res: Response) {
  try {
    const id = parseInt(req.params.id);
    const { name, description, providerName, fieldMapping, phoneFieldPrefix, maxPhoneFields, isActive } = req.body;

    const template = await pdfTemplateService.updateTemplate(id, {
      name,
      description,
      providerName,
      fieldMapping: fieldMapping ? JSON.stringify(fieldMapping) : undefined,
      phoneFieldPrefix,
      maxPhoneFields: maxPhoneFields !== undefined ? parseInt(maxPhoneFields) : undefined,
      isActive,
    });

    await logChange({
      req, action: 'UPDATE', resourceType: 'PdfTemplate',
      resourceId: id.toString(),
      label: `Auftragsvorlage "${template.name}" aktualisiert`,
    });

    res.json({ success: true, data: template });
  } catch (error) {
    res.status(400).json({
      success: false,
      error: error instanceof Error ? error.message : 'Fehler beim Aktualisieren',
    });
  }
}

export async function deleteTemplate(req: AuthRequest, res: Response) {
  try {
    const id = parseInt(req.params.id);
    const template = await pdfTemplateService.getTemplateById(id);
    await pdfTemplateService.deleteTemplate(id);
    await logChange({
      req, action: 'DELETE', resourceType: 'PdfTemplate',
      resourceId: id.toString(),
      label: `Auftragsvorlage "${template?.name}" gelöscht`,
    });
    res.json({ success: true, message: 'Vorlage gelöscht' });
  } catch (error) {
    res.status(400).json({ success: false, error: 'Fehler beim Löschen' });
  }
}

export async function extractFields(req: AuthRequest, res: Response) {
  try {
    const id = parseInt(req.params.id);
    const template = await pdfTemplateService.getTemplateById(id);
    if (!template) return res.status(404).json({ success: false, error: 'Vorlage nicht gefunden' });

    const result = await pdfTemplateService.extractPdfFields(template.templatePath);
    res.json({ success: true, data: result.fields, totalPages: result.totalPages });
  } catch (error) {
    res.status(400).json({
      success: false,
      error: error instanceof Error ? error.message : 'Fehler beim Auslesen der PDF-Felder',
    });
  }
}

export async function getAnnotatedPreview(req: AuthRequest, res: Response) {
  try {
    const id = parseInt(req.params.id);
    const template = await pdfTemplateService.getTemplateById(id);
    if (!template) return res.status(404).json({ success: false, error: 'Vorlage nicht gefunden' });

    const pdfBuffer = await pdfTemplateService.generateAnnotatedPreview(template.templatePath);
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'inline; filename="preview.pdf"');
    res.send(pdfBuffer);
  } catch (error) {
    res.status(400).json({ success: false, error: error instanceof Error ? error.message : 'Fehler' });
  }
}

export async function getCrmFields(req: AuthRequest, res: Response) {
  const maxPhoneFields = req.query.maxPhoneFields ? parseInt(req.query.maxPhoneFields as string) : 8;
  res.json({ success: true, data: pdfTemplateService.getCrmFieldsForTemplate(maxPhoneFields) });
}

export async function getRequiredInputs(req: AuthRequest, res: Response) {
  try {
    const templateId = parseInt(req.params.id);
    const contractId = parseInt(req.params.contractId);
    if (!(await canAccessContract(req, res, contractId))) return;
    const inputs = await pdfTemplateService.getRequiredInputs(templateId, contractId);
    res.json({ success: true, data: inputs });
  } catch (error) {
    res.status(400).json({ success: false, error: error instanceof Error ? error.message : 'Fehler' });
  }
}

export async function generatePdf(req: AuthRequest, res: Response) {
  try {
    const templateId = parseInt(req.params.id);
    const contractId = parseInt(req.params.contractId);
    if (!(await canAccessContract(req, res, contractId))) return;

    // Extras aus Body (POST) oder Query-Parametern (GET)
    const stressfreiEmailId = req.body?.stressfreiEmailId || req.query.stressfreiEmailId;
    const manualValues: Record<string, string> = req.body?.manualValues || {};

    // Manual-Werte aus Query-Parametern extrahieren (manual_manual:1=Wert)
    if (req.query) {
      for (const [key, value] of Object.entries(req.query)) {
        if (key.startsWith('manual_') && typeof value === 'string') {
          manualValues[key.replace('manual_', '')] = value;
        }
      }
    }

    const pdfBuffer = await pdfTemplateService.generateFilledPdf(templateId, contractId, {
      stressfreiEmailId: stressfreiEmailId ? parseInt(stressfreiEmailId as string) : undefined,
      manualValues: Object.keys(manualValues).length > 0 ? manualValues : undefined,
    });

    const template = await pdfTemplateService.getTemplateById(templateId);
    const filename = `${template?.name || 'Auftrag'}_${new Date().toISOString().split('T')[0]}.pdf`;

    await logChange({
      req, action: 'CREATE', resourceType: 'GeneratedPdf',
      label: `PDF "${template?.name}" generiert für Vertrag #${contractId}`,
    });

    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', `inline; filename="${encodeURIComponent(filename)}"`);
    res.send(pdfBuffer);
  } catch (error) {
    console.error('PDF generate error:', error);
    res.status(400).json({
      success: false,
      error: error instanceof Error ? error.message : 'Fehler beim Generieren',
    });
  }
}
