import fs from 'fs';
import multer from 'multer';
import path from 'path';
import { fileURLToPath } from 'url';
import billingService from '../services/billingService.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const BILLING_TEMPLATE_UPLOAD_DIR = path.resolve(__dirname, '..', 'uploads', 'billing-templates');

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const dir = BILLING_TEMPLATE_UPLOAD_DIR;
    fs.mkdirSync(dir, { recursive: true });
    cb(null, dir);
  },
  filename: (req, file, cb) => {
    const ext = path.extname(file.originalname) || '.pdf';
    cb(null, `billing-template-${Date.now()}-${Math.round(Math.random() * 1e9)}${ext}`);
  }
});

const upload = multer({
  storage,
  limits: { fileSize: 10 * 1024 * 1024 },
  fileFilter: (req, file, cb) => {
    const ext = path.extname(file.originalname || '').toLowerCase();
    const isPdf = ext === '.pdf' || (file.mimetype || '').includes('pdf');
    if (!isPdf) {
      return cb(new Error('Nur PDF-Dateien sind erlaubt.'));
    }
    cb(null, true);
  }
});

export const uploadBillingTemplateMiddleware = upload.single('templatePdf');

export const listTemplates = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { clubId } = req.params;
    const result = await billingService.listTemplates(userToken, clubId);
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[listTemplates] Error:', error);
    res.status(500).json({ success: false, error: 'Vorlagen konnten nicht geladen werden.' });
  }
};

export const createTemplate = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { clubId } = req.params;
    const result = await billingService.createTemplate(userToken, clubId, req.body || {}, req.file);
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[createTemplate] Error:', error);
    res.status(500).json({ success: false, error: 'Vorlage konnte nicht gespeichert werden.' });
  }
};

export const deleteTemplate = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { templateId } = req.params;
    const result = await billingService.deleteTemplate(userToken, templateId);
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[deleteTemplate] Error:', error);
    res.status(500).json({ success: false, error: 'Vorlage konnte nicht gelöscht werden.' });
  }
};

export const updateTemplateFields = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { templateId } = req.params;
    const result = await billingService.saveTemplateFields(userToken, templateId, req.body?.fields || []);
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[updateTemplateFields] Error:', error);
    res.status(500).json({ success: false, error: 'Felder konnten nicht gespeichert werden.' });
  }
};

export const createRun = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { clubId } = req.params;
    const result = await billingService.createRun(userToken, clubId, req.body || {});
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[createRun] Error:', error);
    res.status(500).json({ success: false, error: 'Abrechnungslauf konnte nicht erstellt werden.' });
  }
};

export const listRuns = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { clubId } = req.params;
    const result = await billingService.listRuns(userToken, clubId);
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[listRuns] Error:', error);
    res.status(500).json({ success: false, error: 'Abrechnungsläufe konnten nicht geladen werden.' });
  }
};

export const getRunDetails = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { runId } = req.params;
    const result = await billingService.getRunDetails(userToken, runId);
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[getRunDetails] Error:', error);
    res.status(500).json({ success: false, error: 'Abrechnungslauf konnte nicht geladen werden.' });
  }
};

export const deleteRun = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { runId } = req.params;
    const result = await billingService.deleteRun(userToken, runId);
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[deleteRun] Error:', error);
    res.status(500).json({ success: false, error: 'Abrechnung konnte nicht gelöscht werden.' });
  }
};

export const getUserSettings = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { clubId } = req.params;
    const result = await billingService.getUserSettings(userToken, clubId);
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[getUserSettings] Error:', error);
    res.status(500).json({ success: false, error: 'Einstellungen konnten nicht geladen werden.' });
  }
};

export const calculateHoursPreview = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { clubId } = req.params;
    const { monthFrom, monthTo } = req.query;
    const result = await billingService.calculateHoursPreview(userToken, clubId, monthFrom, monthTo);
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[calculateHoursPreview] Error:', error);
    res.status(500).json({ success: false, error: 'Stunden konnten nicht berechnet werden.' });
  }
};

export const generateRun = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { runId } = req.params;
    const result = await billingService.generateRun(userToken, runId, req.body || {});
    res.status(result.status).json(result.response);
  } catch (error) {
    console.error('[generateRun] Error:', error);
    const message = String(error?.message || '');
    if (message.includes('Formularfelder') || message.includes('Feldnamen') || message.includes('Fehlend:')) {
      return res.status(400).json({ success: false, error: message });
    }
    res.status(500).json({ success: false, error: 'Abrechnung konnte nicht erzeugt werden.' });
  }
};

export const downloadTemplatePdf = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { templateId } = req.params;
    const result = await billingService.downloadTemplatePdf(userToken, templateId);
    if (result.status !== 200) {
      return res.status(result.status).json(result.response);
    }
    res.setHeader('Content-Disposition', `inline; filename="${result.file.name}"`);
    res.setHeader('Content-Type', result.file.mimeType);
    return res.sendFile(result.file.path);
  } catch (error) {
    console.error('[downloadTemplatePdf] Error:', error);
    res.status(500).json({ success: false, error: 'PDF konnte nicht geladen werden.' });
  }
};

export const downloadRunPdf = async (req, res) => {
  try {
    const { authcode: userToken } = req.headers;
    const { runId } = req.params;
    const result = await billingService.downloadGeneratedRunPdf(userToken, runId);
    if (result.status !== 200) {
      return res.status(result.status).json(result.response);
    }
    res.setHeader('Content-Disposition', `attachment; filename="${result.file.name}"`);
    res.setHeader('Content-Type', result.file.mimeType);
    return res.sendFile(result.file.path);
  } catch (error) {
    console.error('[downloadRunPdf] Error:', error);
    res.status(500).json({ success: false, error: 'Abrechnungs-PDF konnte nicht geladen werden.' });
  }
};
