import { Request, Response } from 'express';
import checklistService from '../services/checklist.service';
import logger from '../utils/logger';

const param = (req: Request, key: string): string => req.params[key] as string;

class ChecklistController {
  // --- Overview ---

  async getOverviewItems(_req: Request, res: Response): Promise<void> {
    try {
      const data = await checklistService.getOverviewItems();
      res.status(200).json({ success: true, data });
    } catch (error) {
      logger.error('ChecklistController.getOverviewItems error', { error });
      res.status(500).json({ success: false, message: 'Übersichtsdaten konnten nicht geladen werden' });
    }
  }

  // --- Vorlagen (Templates) ---

  async getVorlagen(req: Request, res: Response): Promise<void> {
    try {
      const filter: { aktiv?: boolean } = {};
      if (req.query.aktiv !== undefined) {
        filter.aktiv = req.query.aktiv === 'true';
      }
      const vorlagen = await checklistService.getVorlagen(filter);
      res.status(200).json({ success: true, data: vorlagen });
    } catch (error) {
      logger.error('ChecklistController.getVorlagen error', { error });
      res.status(500).json({ success: false, message: 'Vorlagen konnten nicht geladen werden' });
    }
  }

  async getVorlageById(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const vorlage = await checklistService.getVorlageById(id);
      if (!vorlage) {
        res.status(404).json({ success: false, message: 'Vorlage nicht gefunden' });
        return;
      }
      res.status(200).json({ success: true, data: vorlage });
    } catch (error) {
      logger.error('ChecklistController.getVorlageById error', { error });
      res.status(500).json({ success: false, message: 'Vorlage konnte nicht geladen werden' });
    }
  }

  async createVorlage(req: Request, res: Response): Promise<void> {
    const { name } = req.body;
    if (!name || typeof name !== 'string' || name.trim().length === 0) {
      res.status(400).json({ success: false, message: 'Name ist erforderlich' });
      return;
    }
    try {
      const vorlage = await checklistService.createVorlage(req.body);
      res.status(201).json({ success: true, data: vorlage });
    } catch (error) {
      logger.error('ChecklistController.createVorlage error', { error });
      res.status(500).json({ success: false, message: 'Vorlage konnte nicht erstellt werden' });
    }
  }

  async updateVorlage(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const vorlage = await checklistService.updateVorlage(id, req.body);
      if (!vorlage) {
        res.status(404).json({ success: false, message: 'Vorlage nicht gefunden' });
        return;
      }
      res.status(200).json({ success: true, data: vorlage });
    } catch (error) {
      logger.error('ChecklistController.updateVorlage error', { error });
      res.status(500).json({ success: false, message: 'Vorlage konnte nicht aktualisiert werden' });
    }
  }

  async deleteVorlage(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const vorlage = await checklistService.deleteVorlage(id);
      if (!vorlage) {
        res.status(404).json({ success: false, message: 'Vorlage nicht gefunden' });
        return;
      }
      res.status(200).json({ success: true, message: 'Vorlage gelöscht' });
    } catch (error) {
      logger.error('ChecklistController.deleteVorlage error', { error });
      res.status(500).json({ success: false, message: 'Vorlage konnte nicht gelöscht werden' });
    }
  }

  // --- Vorlage Items ---

  async getVorlageItems(req: Request, res: Response): Promise<void> {
    const vorlageId = parseInt(param(req, 'id'), 10);
    if (isNaN(vorlageId)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const items = await checklistService.getVorlageItems(vorlageId);
      res.status(200).json({ success: true, data: items });
    } catch (error) {
      logger.error('ChecklistController.getVorlageItems error', { error });
      res.status(500).json({ success: false, message: 'Items konnten nicht geladen werden' });
    }
  }

  async addVorlageItem(req: Request, res: Response): Promise<void> {
    const vorlageId = parseInt(param(req, 'id'), 10);
    if (isNaN(vorlageId)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    const { bezeichnung } = req.body;
    if (!bezeichnung || typeof bezeichnung !== 'string' || bezeichnung.trim().length === 0) {
      res.status(400).json({ success: false, message: 'Bezeichnung ist erforderlich' });
      return;
    }
    try {
      const item = await checklistService.addVorlageItem(vorlageId, req.body);
      res.status(201).json({ success: true, data: item });
    } catch (error) {
      logger.error('ChecklistController.addVorlageItem error', { error });
      res.status(500).json({ success: false, message: 'Item konnte nicht erstellt werden' });
    }
  }

  async updateVorlageItem(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const item = await checklistService.updateVorlageItem(id, req.body);
      if (!item) {
        res.status(404).json({ success: false, message: 'Item nicht gefunden' });
        return;
      }
      res.status(200).json({ success: true, data: item });
    } catch (error) {
      logger.error('ChecklistController.updateVorlageItem error', { error });
      res.status(500).json({ success: false, message: 'Item konnte nicht aktualisiert werden' });
    }
  }

  async deleteVorlageItem(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const item = await checklistService.deleteVorlageItem(id);
      if (!item) {
        res.status(404).json({ success: false, message: 'Item nicht gefunden' });
        return;
      }
      res.status(200).json({ success: true, message: 'Item gelöscht' });
    } catch (error) {
      logger.error('ChecklistController.deleteVorlageItem error', { error });
      res.status(500).json({ success: false, message: 'Item konnte nicht gelöscht werden' });
    }
  }

  // --- Vehicle-specific items ---

  async getVehicleItems(req: Request, res: Response): Promise<void> {
    const fahrzeugId = param(req, 'fahrzeugId');
    if (!fahrzeugId) {
      res.status(400).json({ success: false, message: 'Fahrzeug-ID erforderlich' });
      return;
    }
    try {
      const items = await checklistService.getVehicleItems(fahrzeugId);
      res.status(200).json({ success: true, data: items });
    } catch (error) {
      logger.error('ChecklistController.getVehicleItems error', { error });
      res.status(500).json({ success: false, message: 'Items konnten nicht geladen werden' });
    }
  }

  async addVehicleItem(req: Request, res: Response): Promise<void> {
    const fahrzeugId = param(req, 'fahrzeugId');
    if (!fahrzeugId) {
      res.status(400).json({ success: false, message: 'Fahrzeug-ID erforderlich' });
      return;
    }
    const { bezeichnung } = req.body;
    if (!bezeichnung || typeof bezeichnung !== 'string' || bezeichnung.trim().length === 0) {
      res.status(400).json({ success: false, message: 'Bezeichnung ist erforderlich' });
      return;
    }
    try {
      const item = await checklistService.addVehicleItem(fahrzeugId, req.body);
      res.status(201).json({ success: true, data: item });
    } catch (error) {
      logger.error('ChecklistController.addVehicleItem error', { error });
      res.status(500).json({ success: false, message: 'Item konnte nicht erstellt werden' });
    }
  }

  async updateVehicleItem(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const item = await checklistService.updateVehicleItem(id, req.body);
      if (!item) {
        res.status(404).json({ success: false, message: 'Item nicht gefunden' });
        return;
      }
      res.status(200).json({ success: true, data: item });
    } catch (error) {
      logger.error('ChecklistController.updateVehicleItem error', { error });
      res.status(500).json({ success: false, message: 'Item konnte nicht aktualisiert werden' });
    }
  }

  async deleteVehicleItem(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const item = await checklistService.deleteVehicleItem(id);
      if (!item) {
        res.status(404).json({ success: false, message: 'Item nicht gefunden' });
        return;
      }
      res.status(200).json({ success: true, message: 'Item deaktiviert' });
    } catch (error) {
      logger.error('ChecklistController.deleteVehicleItem error', { error });
      res.status(500).json({ success: false, message: 'Item konnte nicht deaktiviert werden' });
    }
  }

  // --- Templates for vehicle ---

  async getTemplatesForVehicle(req: Request, res: Response): Promise<void> {
    const fahrzeugId = param(req, 'fahrzeugId');
    if (!fahrzeugId) {
      res.status(400).json({ success: false, message: 'Fahrzeug-ID erforderlich' });
      return;
    }
    try {
      const templates = await checklistService.getTemplatesForVehicle(fahrzeugId);
      res.status(200).json({ success: true, data: templates });
    } catch (error) {
      logger.error('ChecklistController.getTemplatesForVehicle error', { error });
      res.status(500).json({ success: false, message: 'Checklisten konnten nicht geladen werden' });
    }
  }

  // --- Templates for equipment ---

  async getTemplatesForEquipment(req: Request, res: Response): Promise<void> {
    const ausruestungId = param(req, 'ausruestungId');
    if (!ausruestungId) {
      res.status(400).json({ success: false, message: 'Ausrüstungs-ID erforderlich' });
      return;
    }
    try {
      const templates = await checklistService.getTemplatesForEquipment(ausruestungId);
      res.status(200).json({ success: true, data: templates });
    } catch (error) {
      logger.error('ChecklistController.getTemplatesForEquipment error', { error });
      res.status(500).json({ success: false, message: 'Checklisten konnten nicht geladen werden' });
    }
  }

  // --- Equipment-specific items ---

  async getEquipmentItems(req: Request, res: Response): Promise<void> {
    const ausruestungId = param(req, 'ausruestungId');
    if (!ausruestungId) {
      res.status(400).json({ success: false, message: 'Ausrüstungs-ID erforderlich' });
      return;
    }
    try {
      const items = await checklistService.getEquipmentItems(ausruestungId);
      res.status(200).json({ success: true, data: items });
    } catch (error) {
      logger.error('ChecklistController.getEquipmentItems error', { error });
      res.status(500).json({ success: false, message: 'Items konnten nicht geladen werden' });
    }
  }

  async addEquipmentItem(req: Request, res: Response): Promise<void> {
    const ausruestungId = param(req, 'ausruestungId');
    if (!ausruestungId) {
      res.status(400).json({ success: false, message: 'Ausrüstungs-ID erforderlich' });
      return;
    }
    const { bezeichnung } = req.body;
    if (!bezeichnung || typeof bezeichnung !== 'string' || bezeichnung.trim().length === 0) {
      res.status(400).json({ success: false, message: 'Bezeichnung ist erforderlich' });
      return;
    }
    try {
      const item = await checklistService.addEquipmentItem(ausruestungId, req.body);
      res.status(201).json({ success: true, data: item });
    } catch (error) {
      logger.error('ChecklistController.addEquipmentItem error', { error });
      res.status(500).json({ success: false, message: 'Item konnte nicht erstellt werden' });
    }
  }

  async updateEquipmentItem(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'itemId'), 10);
    if (isNaN(id)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const item = await checklistService.updateEquipmentItem(id, req.body);
      if (!item) {
        res.status(404).json({ success: false, message: 'Item nicht gefunden' });
        return;
      }
      res.status(200).json({ success: true, data: item });
    } catch (error) {
      logger.error('ChecklistController.updateEquipmentItem error', { error });
      res.status(500).json({ success: false, message: 'Item konnte nicht aktualisiert werden' });
    }
  }

  async deleteEquipmentItem(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'itemId'), 10);
    if (isNaN(id)) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const item = await checklistService.deleteEquipmentItem(id);
      if (!item) {
        res.status(404).json({ success: false, message: 'Item nicht gefunden' });
        return;
      }
      res.status(200).json({ success: true, message: 'Item deaktiviert' });
    } catch (error) {
      logger.error('ChecklistController.deleteEquipmentItem error', { error });
      res.status(500).json({ success: false, message: 'Item konnte nicht deaktiviert werden' });
    }
  }

  // --- Ausführungen (Executions) ---

  async startExecution(req: Request, res: Response): Promise<void> {
    const { fahrzeugId, ausruestungId, vorlageId } = req.body;
    if (!vorlageId || (!fahrzeugId && !ausruestungId)) {
      res.status(400).json({ success: false, message: 'vorlageId und entweder fahrzeugId oder ausruestungId sind erforderlich' });
      return;
    }
    try {
      const execution = await checklistService.startExecution(fahrzeugId || null, vorlageId, req.user!.id, ausruestungId || null);
      res.status(201).json({ success: true, data: execution });
    } catch (error) {
      logger.error('ChecklistController.startExecution error', { error });
      res.status(500).json({ success: false, message: 'Ausführung konnte nicht gestartet werden' });
    }
  }

  async submitExecution(req: Request, res: Response): Promise<void> {
    const id = param(req, 'id');
    if (!id) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    const { items, notizen } = req.body;
    if (!Array.isArray(items)) {
      res.status(400).json({ success: false, message: 'items muss ein Array sein' });
      return;
    }
    try {
      const execution = await checklistService.submitExecution(id, items, notizen ?? null, req.user!.id);
      res.status(200).json({ success: true, data: execution });
    } catch (error) {
      logger.error('ChecklistController.submitExecution error', { error });
      res.status(500).json({ success: false, message: 'Ausführung konnte nicht abgeschlossen werden' });
    }
  }

  async approveExecution(req: Request, res: Response): Promise<void> {
    const id = param(req, 'id');
    if (!id) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const execution = await checklistService.approveExecution(id, req.user!.id);
      if (!execution) {
        res.status(404).json({ success: false, message: 'Ausführung nicht gefunden oder Status ungültig' });
        return;
      }
      res.status(200).json({ success: true, data: execution });
    } catch (error) {
      logger.error('ChecklistController.approveExecution error', { error });
      res.status(500).json({ success: false, message: 'Freigabe konnte nicht erteilt werden' });
    }
  }

  async getExecutions(req: Request, res: Response): Promise<void> {
    try {
      const filter: { fahrzeugId?: string; ausruestungId?: string; vorlageId?: number; status?: string } = {};
      if (req.query.fahrzeugId) filter.fahrzeugId = req.query.fahrzeugId as string;
      if (req.query.ausruestungId) filter.ausruestungId = req.query.ausruestungId as string;
      if (req.query.vorlageId) filter.vorlageId = parseInt(req.query.vorlageId as string, 10);
      if (req.query.status) filter.status = req.query.status as string;
      const executions = await checklistService.getExecutions(filter);
      res.status(200).json({ success: true, data: executions });
    } catch (error) {
      logger.error('ChecklistController.getExecutions error', { error });
      res.status(500).json({ success: false, message: 'Ausführungen konnten nicht geladen werden' });
    }
  }

  async getExecutionById(req: Request, res: Response): Promise<void> {
    const id = param(req, 'id');
    if (!id) {
      res.status(400).json({ success: false, message: 'Ungültige ID' });
      return;
    }
    try {
      const execution = await checklistService.getExecutionById(id);
      if (!execution) {
        res.status(404).json({ success: false, message: 'Ausführung nicht gefunden' });
        return;
      }
      res.status(200).json({ success: true, data: execution });
    } catch (error) {
      logger.error('ChecklistController.getExecutionById error', { error });
      res.status(500).json({ success: false, message: 'Ausführung konnte nicht geladen werden' });
    }
  }

  // --- Fälligkeiten ---

  async getOverdueChecklists(_req: Request, res: Response): Promise<void> {
    try {
      const overdue = await checklistService.getOverdueChecklists();
      res.status(200).json({ success: true, data: overdue });
    } catch (error) {
      logger.error('ChecklistController.getOverdueChecklists error', { error });
      res.status(500).json({ success: false, message: 'Überfällige Checklisten konnten nicht geladen werden' });
    }
  }

  async getDueChecklists(req: Request, res: Response): Promise<void> {
    const fahrzeugId = param(req, 'fahrzeugId');
    if (!fahrzeugId) {
      res.status(400).json({ success: false, message: 'Fahrzeug-ID erforderlich' });
      return;
    }
    try {
      const due = await checklistService.getDueChecklists(fahrzeugId);
      res.status(200).json({ success: true, data: due });
    } catch (error) {
      logger.error('ChecklistController.getDueChecklists error', { error });
      res.status(500).json({ success: false, message: 'Fälligkeiten konnten nicht geladen werden' });
    }
  }
}

export default new ChecklistController();
