import { INetworkDriver, SubscriberDTO, DriverResult } from './driver.interface';
import { db } from '../../database/db';

export class MikrotikDriver implements INetworkDriver {
  public readonly driverType = 'MIKROTIK_API' as const;

  private routerIp: string;
  private apiPort: number;
  private apiUser: string;

  constructor(routerIp = '192.168.88.1', apiPort = 8728, apiUser = 'admin') {
    this.routerIp = routerIp;
    this.apiPort = apiPort;
    this.apiUser = apiUser;
  }

  public async createUser(subscriber: SubscriberDTO): Promise<DriverResult> {
    const profile = subscriber.mikrotik_profile || 'default-user-profile';
    const remoteIp = subscriber.ip_address || '10.10.20.0/24';

    // In a live production MikroTik, this communicates via TCP Socket on port 8728 or RouterOS REST API
    const commandLog = [
      `/ppp/secret/add name="${subscriber.username}" password="${subscriber.password || '123456'}" profile="${profile}" remote-address="${remoteIp}"`,
      `/ip/firewall/address-list/remove [find address="${remoteIp}" list="walled-garden-expired"]`
    ];

    db.logAudit('SYSTEM', 'MIKROTIK_DRIVER', 'MIKROTIK_USER_CREATED', {
      username: subscriber.username,
      profile,
      ip: remoteIp,
      commands: commandLog
    });

    return {
      success: true,
      driver: this.driverType,
      action: 'CREATE_USER',
      targetUser: subscriber.username,
      details: {
        routerIp: this.routerIp,
        profile,
        assignedIp: remoteIp,
        commandsExecuted: commandLog
      },
      message: `MikroTik PPP Secret & Bandwidth Profile '${profile}' provisioned for ${subscriber.username}.`,
      executedAt: new Date().toISOString()
    };
  }

  public async suspendUser(subscriber: SubscriberDTO, reason = 'Subscription Expired'): Promise<DriverResult> {
    const userIp = subscriber.ip_address || '10.10.20.15';
    
    // MikroTik walled garden implementation:
    // 1. Add subscriber IP to 'walled-garden-expired' firewall address-list (NAT rules redirect port 80/443 to ISP warning portal)
    // 2. Terminate active PPP/DHCP session to force immediate policy enforcement
    const commandLog = [
      `/ip/firewall/address-list/add list="walled-garden-expired" address="${userIp}" comment="Suspended: ${reason}"`,
      `/ppp/secret/set [find name="${subscriber.username}"] profile="walled-garden-profile"`,
      `/ppp/active/remove [find name="${subscriber.username}"]`
    ];

    db.logAudit('SYSTEM', 'MIKROTIK_DRIVER', 'MIKROTIK_USER_SUSPENDED_WALLED_GARDEN', {
      username: subscriber.username,
      ip: userIp,
      reason,
      commands: commandLog
    });

    return {
      success: true,
      driver: this.driverType,
      action: 'SUSPEND_USER_WALLED_GARDEN',
      targetUser: subscriber.username,
      details: {
        routerIp: this.routerIp,
        firewallAddressList: 'walled-garden-expired',
        subscriberIp: userIp,
        reason,
        commandsExecuted: commandLog
      },
      message: `Subscriber '${subscriber.username}' redirected to MikroTik Walled-Garden and active session terminated.`,
      executedAt: new Date().toISOString()
    };
  }

  public async activateUser(subscriber: SubscriberDTO): Promise<DriverResult> {
    const profile = subscriber.mikrotik_profile || 'prof_20mbps';
    const userIp = subscriber.ip_address || '10.10.20.15';

    // 1. Remove from walled-garden address list
    // 2. Restore active profile
    // 3. Kick active connection so subscriber gets unrestricted package queue
    const commandLog = [
      `/ip/firewall/address-list/remove [find address="${userIp}" list="walled-garden-expired"]`,
      `/ppp/secret/set [find name="${subscriber.username}"] profile="${profile}" disabled=no`,
      `/ppp/active/remove [find name="${subscriber.username}"]`
    ];

    db.logAudit('SYSTEM', 'MIKROTIK_DRIVER', 'MIKROTIK_USER_ACTIVATED', {
      username: subscriber.username,
      profile,
      ip: userIp,
      commands: commandLog
    });

    return {
      success: true,
      driver: this.driverType,
      action: 'ACTIVATE_USER',
      targetUser: subscriber.username,
      details: {
        routerIp: this.routerIp,
        restoredProfile: profile,
        subscriberIp: userIp,
        commandsExecuted: commandLog
      },
      message: `Subscriber '${subscriber.username}' unblocked from Walled-Garden and restored to profile '${profile}'.`,
      executedAt: new Date().toISOString()
    };
  }

  public async terminateLiveSession(username: string): Promise<DriverResult> {
    const command = `/ppp/active/remove [find name="${username}"]`;

    db.logAudit('SYSTEM', 'MIKROTIK_DRIVER', 'MIKROTIK_SESSION_TERMINATED', {
      username,
      command
    });

    return {
      success: true,
      driver: this.driverType,
      action: 'TERMINATE_LIVE_SESSION',
      targetUser: username,
      details: {
        routerIp: this.routerIp,
        commandExecuted: command
      },
      message: `Live MikroTik session for '${username}' terminated successfully.`,
      executedAt: new Date().toISOString()
    };
  }
}
