import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  Index,
  Unique,
} from 'typeorm';

/**
 * Session fingerprint - stores device and attribution data per session
 * Attribution is first-touch: only set on creation, never overwritten
 * IP addresses are NEVER stored - only hashed for audit purposes
 */
@Entity('session_fingerprints')
@Unique(['sessionId'])
@Index(['userId'])
@Index(['trafficSource'])
@Index(['createdAt'])
export class SessionFingerprint {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  /** Session identifier (client-generated) */
  @Column({ type: 'varchar', length: 64 })
  sessionId!: string;

  /** User ID if authenticated (can be set later) */
  @Column({ type: 'varchar', length: 64, nullable: true })
  userId?: string | null;

  // ─────────────────────────────────────────────────────────────────────────────
  // Device Information
  // ─────────────────────────────────────────────────────────────────────────────

  /** Device type: 'desktop' | 'mobile' | 'tablet' | 'bot' */
  @Column({ type: 'varchar', length: 20, nullable: true })
  deviceType?: string | null;

  /** Whether session appears to be a bot */
  @Column({ type: 'boolean', default: false })
  isBot!: boolean;

  /** Browser name (e.g., 'Chrome', 'Firefox') */
  @Column({ type: 'varchar', length: 50, nullable: true })
  browser?: string | null;

  /** Browser version */
  @Column({ type: 'varchar', length: 30, nullable: true })
  browserVersion?: string | null;

  /** Browser major version */
  @Column({ type: 'int', nullable: true })
  browserMajor?: number | null;

  /** Operating system name */
  @Column({ type: 'varchar', length: 50, nullable: true })
  os?: string | null;

  /** OS version */
  @Column({ type: 'varchar', length: 30, nullable: true })
  osVersion?: string | null;

  /** Device vendor (e.g., 'Apple', 'Samsung') */
  @Column({ type: 'varchar', length: 50, nullable: true })
  deviceVendor?: string | null;

  /** Device model */
  @Column({ type: 'varchar', length: 50, nullable: true })
  deviceModel?: string | null;

  // ─────────────────────────────────────────────────────────────────────────────
  // Screen & Viewport
  // ─────────────────────────────────────────────────────────────────────────────

  @Column({ type: 'int', nullable: true })
  screenWidth?: number | null;

  @Column({ type: 'int', nullable: true })
  screenHeight?: number | null;

  @Column({ type: 'int', nullable: true })
  viewportWidth?: number | null;

  @Column({ type: 'int', nullable: true })
  viewportHeight?: number | null;

  @Column({ type: 'real', nullable: true })
  pixelRatio?: number | null;

  @Column({ type: 'int', nullable: true })
  colorDepth?: number | null;

  // ─────────────────────────────────────────────────────────────────────────────
  // Locale & Timezone
  // ─────────────────────────────────────────────────────────────────────────────

  /** Primary language (e.g., 'en-US') */
  @Column({ type: 'varchar', length: 20, nullable: true })
  language?: string | null;

  /** All accepted languages */
  @Column({ type: 'varchar', array: true, nullable: true })
  languages?: string[] | null;

  /** Timezone from client (e.g., 'America/New_York') */
  @Column({ type: 'varchar', length: 50, nullable: true })
  timezone?: string | null;

  /** Timezone offset in minutes */
  @Column({ type: 'int', nullable: true })
  timezoneOffset?: number | null;

  // ─────────────────────────────────────────────────────────────────────────────
  // Geolocation (from IP lookup, IP NOT stored)
  // ─────────────────────────────────────────────────────────────────────────────

  /** ISO country code */
  @Column({ type: 'varchar', length: 2, nullable: true })
  @Index()
  country?: string | null;

  /** Region/state code */
  @Column({ type: 'varchar', length: 50, nullable: true })
  region?: string | null;

  /** City name */
  @Column({ type: 'varchar', length: 100, nullable: true })
  city?: string | null;

  /** Whether user is in EU (for GDPR) */
  @Column({ type: 'boolean', nullable: true })
  isEU?: boolean | null;

  /** Timezone from geo lookup */
  @Column({ type: 'varchar', length: 50, nullable: true })
  geoTimezone?: string | null;

  // ─────────────────────────────────────────────────────────────────────────────
  // Privacy & Security Signals
  // ─────────────────────────────────────────────────────────────────────────────

  /** VPN detected */
  @Column({ type: 'boolean', nullable: true })
  isVpn?: boolean | null;

  /** Datacenter IP detected */
  @Column({ type: 'boolean', nullable: true })
  isDatacenter?: boolean | null;

  /** Tor exit node detected */
  @Column({ type: 'boolean', nullable: true })
  isTor?: boolean | null;

  /** Government/law-enforcement/military/intelligence network detected */
  @Column({ type: 'boolean', nullable: true })
  isGovernment?: boolean | null;

  /**
   * Organization type from gov-detection
   * NORMAL | LIBRARY | EDUCATION | GOVERNMENT | LAW_ENFORCEMENT | MILITARY | INTELLIGENCE | UNKNOWN
   */
  @Column({ type: 'varchar', length: 30, nullable: true })
  orgType?: string | null;

  /** Response tier from gov-detection: ALLOW | SOFT_BLOCK | HARD_BLOCK | ALERT */
  @Column({ type: 'varchar', length: 20, nullable: true })
  responseTier?: string | null;

  /** ASN organization name */
  @Column({ type: 'varchar', length: 200, nullable: true })
  org?: string | null;

  /** ASN number */
  @Column({ type: 'int', nullable: true })
  asn?: number | null;

  /** IP hash for audit (NOT the actual IP) */
  @Column({ type: 'varchar', length: 64, nullable: true })
  ipHash?: string | null;

  // ─────────────────────────────────────────────────────────────────────────────
  // Hardware Capabilities
  // ─────────────────────────────────────────────────────────────────────────────

  /** Device memory in GB */
  @Column({ type: 'real', nullable: true })
  deviceMemory?: number | null;

  /** CPU cores */
  @Column({ type: 'int', nullable: true })
  hardwareConcurrency?: number | null;

  /** Max touch points */
  @Column({ type: 'int', nullable: true })
  touchPoints?: number | null;

  /** Cookies enabled */
  @Column({ type: 'boolean', nullable: true })
  cookiesEnabled?: boolean | null;

  /** Do Not Track header set */
  @Column({ type: 'boolean', nullable: true })
  doNotTrack?: boolean | null;

  // ─────────────────────────────────────────────────────────────────────────────
  // First-Touch Attribution (NEVER overwritten after creation)
  // ─────────────────────────────────────────────────────────────────────────────

  /** Resolved traffic source: 'organic' | 'direct' | 'social' | 'paid' | 'email' | 'referral' */
  @Column({ type: 'varchar', length: 30, nullable: true })
  @Index()
  trafficSource?: string | null;

  /** UTM source parameter */
  @Column({ type: 'varchar', length: 255, nullable: true })
  utmSource?: string | null;

  /** UTM medium parameter */
  @Column({ type: 'varchar', length: 255, nullable: true })
  utmMedium?: string | null;

  /** UTM campaign parameter */
  @Column({ type: 'varchar', length: 255, nullable: true })
  utmCampaign?: string | null;

  /** UTM content parameter */
  @Column({ type: 'varchar', length: 255, nullable: true })
  utmContent?: string | null;

  /** UTM term parameter */
  @Column({ type: 'varchar', length: 255, nullable: true })
  utmTerm?: string | null;

  /** Original referrer URL */
  @Column({ type: 'text', nullable: true })
  referrer?: string | null;

  /** Landing page URL */
  @Column({ type: 'text', nullable: true })
  landingPage?: string | null;

  // ─────────────────────────────────────────────────────────────────────────────
  // Timestamps
  // ─────────────────────────────────────────────────────────────────────────────

  @CreateDateColumn({ type: 'timestamptz' })
  createdAt!: Date;

  @UpdateDateColumn({ type: 'timestamptz' })
  updatedAt!: Date;
}
