import { AlertStage, AlertType, AttackType } from '../../../common/enum/alert.enum';
import { BeforeInsert, BeforeUpdate, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm';

@Entity('alerts')
export class Alert {
  @PrimaryGeneratedColumn()
  id: string;

  @Column({ name: 'title', charset: 'utf8mb4', collation: 'utf8mb4_general_ci' })
  title: string;

  @Column({ type: 'text', name: 'description', charset: 'utf8mb4', collation: 'utf8mb4_general_ci' })
  description: string;

  @Column({ name: 'source' })
  source: string;

  @Column({ name: 'source_url', nullable: true })
  sourceUrl: string;

  @Column({ name: 'attack_time', type: 'timestamp', nullable: true })
  attackTime: Date;

  @Column({ name: 'target_country' })
  targetCountry: string;

  @Column({ name: 'target_organization' })
  targetOrganization: string;

  @Column({ name: 'attacker_info', nullable: true })
  attackerInfo: string;

  @Column({
    name: 'attack_type',
    type: 'enum',
    enum: AttackType,
    default: AttackType.OTHER,
  })
  attackType: AttackType;

  @Column({
    name: 'stage',
    type: 'enum',
    enum: AlertStage,
    default: AlertStage.GATHERED,
  })
  stage: AlertStage;

  @Column({
    name: 'type',
    type: 'enum',
    enum: AlertType,
    default: AlertType.AUTOMATIC,
  })
  type: AlertType;

  @Column({ name: 'is_verified', default: false })
  isVerified: boolean;

  @Column({ name: 'verified_by', nullable: true })
  verifiedBy: string;

  @Column({ name: 'verified_at', type: 'timestamp', nullable: true })
  verifiedAt: Date;

  @Column({ name: 'score', default: 0, nullable: true })
  score: number;

  @Column({ name: 'severity', nullable: true })
  severity: number;

  @Column({ name: 'is_relevant_to_nepal', default: false })
  isRelevantToNepal: boolean;

  @Column({ name: 'sent_to_newsletter', default: false })
  sentToNewsletter: boolean;

  @Column({ name: 'newsletter_id', nullable: true })
  newsletterId: string;

  @Column({ name: 'poster_name', nullable: true })
  posterName: string;

  @Column({ name: 'poster_url', nullable: true })
  posterUrl: string;

  @CreateDateColumn({ name: 'created_at' })
  createdAt: Date;

  @UpdateDateColumn({ name: 'updated_at' })
  updatedAt: Date;

  @BeforeInsert()
  @BeforeUpdate()
  calculateScore() {
    if (this.score !== undefined && this.score !== null && this.score !== 0) {
      // If score is manually set, do not recalculate
      return;
    }

    let score = 0;

    // Assign weights based on severity (assuming max severity is 10)
    if (this.severity) {
      score += this.severity * 10;
    }

    // Increase score for verified alerts
    if (this.isVerified) {
      score += 20;
    }

    // Weight based on attack type
    const attackTypeWeights: Record<AttackType, number> = {
      [AttackType.DDOS]: 10,
      [AttackType.MALWARE]: 15,
      [AttackType.PHISHING]: 20,
      [AttackType.RANSOMWARE]: 25,
      [AttackType.DATA_BREACH]: 30,
      [AttackType.VGS]: 5,
      [AttackType.OTHER]: 5,
      [AttackType.EXPLOIT]: 10,
      [AttackType.SCAM]: 10,
      [AttackType.SOCIAL_ENGINEERING]: 15,
      [AttackType.SPAM]: 5,
      [AttackType.BOTNET]: 10,
      [AttackType.APT]: 20,
      [AttackType.SQL_INJECTION]: 15,
      [AttackType.XSS]: 15,
      [AttackType.CSRF]: 15,
      [AttackType.MITM]: 20,
      [AttackType.DNS_ATTACK]: 15,
      [AttackType.PHYSICAL_ATTACK]: 20,
      [AttackType.NETWORK_ATTACK]: 20,
      [AttackType.APPLICATION_ATTACK]: 20,
      [AttackType.CLOUD_ATTACK]: 20,
      [AttackType.IOT_ATTACK]: 15,
      [AttackType.SUPPLY_CHAIN_ATTACK]: 20,
      [AttackType.INSIDER_THREAT]: 20,
      [AttackType.ZERO_DAY]: 25,
      [AttackType.PRIVILEGE_ESCALATION]: 20,
      [AttackType.DENIAL_OF_SERVICE]: 20,
      [AttackType.ACCOUNT_COMPROMISE]: 20,
      [AttackType.CREDENTIAL_STUFFING]: 15,
      [AttackType.DOMAIN_HIJACKING]: 15,
      [AttackType.EMAIL_COMPROMISE]: 20,
      [AttackType.WEB_APPLICATION_ATTACK]: 20,
      [AttackType.CLOUD_SERVICE_ATTACK]: 20,
      [AttackType.SOCIAL_MEDIA_ATTACK]: 15,
      [AttackType.MOBILE_ATTACK]: 15,
      [AttackType.API_ATTACK]: 20,
      [AttackType.CYBER_ATTACK]: 20,
    };
    score += attackTypeWeights[this.attackType] || 0;

    // Boost score if relevant to Nepal
    if (this.isRelevantToNepal) {
      score += 15;
    }

    // Define the maximum possible score based on highest possible values
    const MAX_POSSIBLE_SCORE = 10 * 10 + 20 + 30 + 15; // (Max severity * 10) + Verified + Highest attack weight + Nepal relevance

    // Normalize score to a 0-10 scale
    this.score = Math.min(10, Math.max(0, (score / MAX_POSSIBLE_SCORE) * 10));
  }
}
