import * as plugins from '../../plugins.ts';
import type { OpsServer } from '../classes.opsserver.ts';
import * as interfaces from '../../../ts_interfaces/index.ts';
import { requireValidIdentity } from '../helpers/guards.ts';

export class SettingsHandler {
  public typedrouter = new plugins.typedrequest.TypedRouter();

  constructor(private opsServerRef: OpsServer) {
    this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
    this.registerHandlers();
  }

  private getSettingsObject(): interfaces.data.ISettings {
    const db = this.opsServerRef.oneboxRef.database;
    const settingsMap = db.getAllSettings(); // Returns Record<string, string>

    return {
      cloudflareToken: settingsMap['cloudflareToken'] || '',
      cloudflareZoneId: settingsMap['cloudflareZoneId'] || '',
      autoRenewCerts: settingsMap['autoRenewCerts'] === 'true',
      renewalThreshold: parseInt(settingsMap['renewalThreshold'] || '30', 10),
      acmeEmail: settingsMap['acmeEmail'] || '',
      httpPort: parseInt(settingsMap['httpPort'] || '80', 10),
      httpsPort: parseInt(settingsMap['httpsPort'] || '443', 10),
      forceHttps: settingsMap['forceHttps'] === 'true',
    };
  }

  private registerHandlers(): void {
    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetSettings>(
        'getSettings',
        async (dataArg) => {
          await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
          const settings = this.getSettingsObject();
          return { settings };
        },
      ),
    );

    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateSettings>(
        'updateSettings',
        async (dataArg) => {
          await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
          const db = this.opsServerRef.oneboxRef.database;
          const updates = dataArg.settings;

          // Store each setting as key-value pair
          for (const [key, value] of Object.entries(updates)) {
            if (value !== undefined) {
              db.setSetting(key, String(value));
            }
          }

          const settings = this.getSettingsObject();
          return { settings };
        },
      ),
    );

    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_SetBackupPassword>(
        'setBackupPassword',
        async (dataArg) => {
          await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
          this.opsServerRef.oneboxRef.database.setSetting('backupPassword', dataArg.password);
          return { ok: true };
        },
      ),
    );

    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetBackupPasswordStatus>(
        'getBackupPasswordStatus',
        async (dataArg) => {
          await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
          const backupPassword = this.opsServerRef.oneboxRef.database.getSetting('backupPassword');
          const isConfigured = !!backupPassword;
          return { status: { isConfigured } };
        },
      ),
    );
  }
}
