import pool from '../config/database';
import logger from '../utils/logger';

export interface CleanupResult {
  count: number;
  deleted: boolean;
}

class CleanupService {

  async cleanupNotifications(olderThanDays: number, confirm: boolean): Promise<CleanupResult> {
    const cutoff = `${olderThanDays} days`;
    if (!confirm) {
      const { rows } = await pool.query(
        `SELECT COUNT(*)::int AS count FROM benachrichtigungen WHERE erstellt_am < NOW() - $1::interval`,
        [cutoff]
      );
      return { count: rows[0].count, deleted: false };
    }
    const { rowCount } = await pool.query(
      `DELETE FROM benachrichtigungen WHERE erstellt_am < NOW() - $1::interval`,
      [cutoff]
    );
    logger.info(`Cleanup: deleted ${rowCount} notifications older than ${olderThanDays} days`);
    return { count: rowCount ?? 0, deleted: true };
  }

  async cleanupAuditLog(olderThanDays: number, confirm: boolean): Promise<CleanupResult> {
    const cutoff = `${olderThanDays} days`;
    if (!confirm) {
      const { rows } = await pool.query(
        `SELECT COUNT(*)::int AS count FROM audit_log WHERE created_at < NOW() - $1::interval`,
        [cutoff]
      );
      return { count: rows[0].count, deleted: false };
    }
    const { rowCount } = await pool.query(
      `DELETE FROM audit_log WHERE created_at < NOW() - $1::interval`,
      [cutoff]
    );
    logger.info(`Cleanup: deleted ${rowCount} audit_log entries older than ${olderThanDays} days`);
    return { count: rowCount ?? 0, deleted: true };
  }

  async cleanupEvents(olderThanDays: number, confirm: boolean): Promise<CleanupResult> {
    const cutoff = `${olderThanDays} days`;
    if (!confirm) {
      const { rows } = await pool.query(
        `SELECT COUNT(*)::int AS count FROM events WHERE end_date < NOW() - $1::interval`,
        [cutoff]
      );
      return { count: rows[0].count, deleted: false };
    }
    const { rowCount } = await pool.query(
      `DELETE FROM events WHERE end_date < NOW() - $1::interval`,
      [cutoff]
    );
    logger.info(`Cleanup: deleted ${rowCount} events older than ${olderThanDays} days`);
    return { count: rowCount ?? 0, deleted: true };
  }

  async cleanupBookings(olderThanDays: number, confirm: boolean): Promise<CleanupResult> {
    const cutoff = `${olderThanDays} days`;
    if (!confirm) {
      const { rows } = await pool.query(
        `SELECT COUNT(*)::int AS count FROM fahrzeug_buchungen WHERE end_date < NOW() - $1::interval AND status IN ('completed', 'cancelled')`,
        [cutoff]
      );
      return { count: rows[0].count, deleted: false };
    }
    const { rowCount } = await pool.query(
      `DELETE FROM fahrzeug_buchungen WHERE end_date < NOW() - $1::interval AND status IN ('completed', 'cancelled')`,
      [cutoff]
    );
    logger.info(`Cleanup: deleted ${rowCount} bookings older than ${olderThanDays} days`);
    return { count: rowCount ?? 0, deleted: true };
  }

  async cleanupOrders(olderThanDays: number, confirm: boolean): Promise<CleanupResult> {
    const cutoff = `${olderThanDays} days`;
    if (!confirm) {
      const { rows } = await pool.query(
        `SELECT COUNT(*)::int AS count FROM bestellungen WHERE updated_at < NOW() - $1::interval AND status = 'abgeschlossen'`,
        [cutoff]
      );
      return { count: rows[0].count, deleted: false };
    }
    const { rowCount } = await pool.query(
      `DELETE FROM bestellungen WHERE updated_at < NOW() - $1::interval AND status = 'abgeschlossen'`,
      [cutoff]
    );
    logger.info(`Cleanup: deleted ${rowCount} orders older than ${olderThanDays} days`);
    return { count: rowCount ?? 0, deleted: true };
  }

  async cleanupVehicleHistory(olderThanDays: number, confirm: boolean): Promise<CleanupResult> {
    const cutoff = `${olderThanDays} days`;
    if (!confirm) {
      const { rows } = await pool.query(
        `SELECT COUNT(*)::int AS count FROM fahrzeug_wartungslog WHERE datum < NOW() - $1::interval`,
        [cutoff]
      );
      return { count: rows[0].count, deleted: false };
    }
    const { rowCount } = await pool.query(
      `DELETE FROM fahrzeug_wartungslog WHERE datum < NOW() - $1::interval`,
      [cutoff]
    );
    logger.info(`Cleanup: deleted ${rowCount} vehicle history entries older than ${olderThanDays} days`);
    return { count: rowCount ?? 0, deleted: true };
  }

  async cleanupEquipmentHistory(olderThanDays: number, confirm: boolean): Promise<CleanupResult> {
    const cutoff = `${olderThanDays} days`;
    if (!confirm) {
      const { rows } = await pool.query(
        `SELECT COUNT(*)::int AS count FROM ausruestung_wartungslog WHERE datum < NOW() - $1::interval`,
        [cutoff]
      );
      return { count: rows[0].count, deleted: false };
    }
    const { rowCount } = await pool.query(
      `DELETE FROM ausruestung_wartungslog WHERE datum < NOW() - $1::interval`,
      [cutoff]
    );
    logger.info(`Cleanup: deleted ${rowCount} equipment history entries older than ${olderThanDays} days`);
    return { count: rowCount ?? 0, deleted: true };
  }

  async resetBestellungenSequence(confirm: boolean): Promise<CleanupResult> {
    if (!confirm) {
      const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM bestellungen');
      return { count: rows[0].count, deleted: false };
    }
    const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM bestellungen');
    const count = rows[0].count;
    // Delete related linking tables first, then main table
    await pool.query('DELETE FROM ausruestung_anfrage_bestellung WHERE bestellung_id IN (SELECT id FROM bestellungen)');
    await pool.query('TRUNCATE bestellungen CASCADE');
    try { await pool.query('ALTER SEQUENCE bestellungen_id_seq RESTART WITH 1'); } catch { /* sequence may not exist */ }
    logger.info(`Cleanup: truncated bestellungen (${count} rows) and reset sequence`);
    return { count, deleted: true };
  }

  async resetAusruestungAnfragenSequence(confirm: boolean): Promise<CleanupResult> {
    if (!confirm) {
      const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM ausruestung_anfragen');
      return { count: rows[0].count, deleted: false };
    }
    const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM ausruestung_anfragen');
    const count = rows[0].count;
    // Delete linking table first
    await pool.query('DELETE FROM ausruestung_anfrage_bestellung WHERE anfrage_id IN (SELECT id FROM ausruestung_anfragen)');
    await pool.query('TRUNCATE ausruestung_anfragen CASCADE');
    try { await pool.query('ALTER SEQUENCE ausruestung_anfragen_id_seq RESTART WITH 1'); } catch { /* sequence may not exist */ }
    logger.info(`Cleanup: truncated ausruestung_anfragen (${count} rows) and reset sequence`);
    return { count, deleted: true };
  }

  async cleanupChecklistHistory(olderThanDays: number, confirm: boolean): Promise<CleanupResult> {
    const cutoff = `${olderThanDays} days`;
    if (!confirm) {
      const { rows } = await pool.query(
        `SELECT COUNT(*)::int AS count FROM checklist_ausfuehrungen WHERE ausgefuehrt_am < NOW() - $1::interval`,
        [cutoff]
      );
      return { count: rows[0].count, deleted: false };
    }
    const { rowCount } = await pool.query(
      `DELETE FROM checklist_ausfuehrungen WHERE ausgefuehrt_am < NOW() - $1::interval`,
      [cutoff]
    );
    logger.info(`Cleanup: deleted ${rowCount} checklist executions older than ${olderThanDays} days`);
    return { count: rowCount ?? 0, deleted: true };
  }

  async resetChecklistHistory(confirm: boolean): Promise<CleanupResult> {
    if (!confirm) {
      const { rows } = await pool.query(`SELECT COUNT(*)::int AS count FROM checklist_ausfuehrungen`);
      return { count: rows[0].count, deleted: false };
    }
    await pool.query(`TRUNCATE checklist_ausfuehrungen CASCADE`);
    await pool.query(`TRUNCATE checklist_faelligkeit CASCADE`);
    logger.info('Cleanup: reset all checklist history');
    return { count: 0, deleted: true };
  }

  async resetIssuesSequence(confirm: boolean): Promise<CleanupResult> {
    if (!confirm) {
      const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM issues');
      return { count: rows[0].count, deleted: false };
    }
    const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM issues');
    const count = rows[0].count;
    await pool.query('TRUNCATE issues CASCADE');
    try { await pool.query('ALTER SEQUENCE issues_id_seq RESTART WITH 1'); } catch { /* sequence may not exist */ }
    logger.info(`Cleanup: truncated issues (${count} rows) and reset sequence`);
    return { count, deleted: true };
  }

  async resetBuchhaltungTransaktionen(confirm: boolean): Promise<CleanupResult> {
    if (!confirm) {
      const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM buchhaltung_transaktionen');
      return { count: rows[0].count, deleted: false };
    }
    const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM buchhaltung_transaktionen');
    const count = rows[0].count;
    await pool.query('TRUNCATE buchhaltung_transaktionen CASCADE');
    try { await pool.query('ALTER SEQUENCE buchhaltung_transaktionen_id_seq RESTART WITH 1'); } catch { /* sequence may not exist */ }
    logger.info(`Cleanup: truncated buchhaltung_transaktionen (${count} rows) and reset sequence`);
    return { count, deleted: true };
  }

  async resetBuchhaltungKonten(confirm: boolean): Promise<CleanupResult> {
    if (!confirm) {
      const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM buchhaltung_konten');
      return { count: rows[0].count, deleted: false };
    }
    const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM buchhaltung_konten');
    const count = rows[0].count;
    await pool.query('TRUNCATE buchhaltung_transaktionen CASCADE');
    await pool.query('TRUNCATE buchhaltung_konten CASCADE');
    try { await pool.query('ALTER SEQUENCE buchhaltung_konten_id_seq RESTART WITH 1'); } catch { /* sequence may not exist */ }
    try { await pool.query('ALTER SEQUENCE buchhaltung_transaktionen_id_seq RESTART WITH 1'); } catch { /* sequence may not exist */ }
    logger.info(`Cleanup: truncated buchhaltung_konten (${count} rows) and reset sequence`);
    return { count, deleted: true };
  }

  async resetBuchhaltungBankkonten(confirm: boolean): Promise<CleanupResult> {
    if (!confirm) {
      const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM buchhaltung_bankkonten');
      return { count: rows[0].count, deleted: false };
    }
    const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM buchhaltung_bankkonten');
    const count = rows[0].count;
    await pool.query('TRUNCATE buchhaltung_bankkonten CASCADE');
    try { await pool.query('ALTER SEQUENCE buchhaltung_bankkonten_id_seq RESTART WITH 1'); } catch { /* sequence may not exist */ }
    logger.info(`Cleanup: truncated buchhaltung_bankkonten (${count} rows) and reset sequence`);
    return { count, deleted: true };
  }

  async resetPersoenlicheAusruestung(confirm: boolean): Promise<CleanupResult> {
    if (!confirm) {
      const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM persoenliche_ausruestung WHERE geloescht_am IS NULL');
      return { count: rows[0].count, deleted: false };
    }
    const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM persoenliche_ausruestung');
    const count = rows[0].count;
    // Clear FK references from request positions before truncating
    await pool.query(`UPDATE ausruestung_anfrage_positionen SET zuweisung_persoenlich_id = NULL, zuweisung_typ = 'keine' WHERE zuweisung_persoenlich_id IS NOT NULL`);
    // CASCADE removes persoenliche_ausruestung_eigenschaften rows automatically
    await pool.query('TRUNCATE persoenliche_ausruestung CASCADE');
    logger.info(`Cleanup: truncated persoenliche_ausruestung (${count} rows)`);
    return { count, deleted: true };
  }
}

export default new CleanupService();
