import {
  Column,
  CreateDateColumn,
  Entity,
  Index,
  JoinColumn,
  ManyToOne,
  OneToMany,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
} from 'typeorm';
import { User } from '../../user/entities/user.entity';
import { Company } from '../../companies/entities/company.entity';
import { AuditScheduleRow } from '../../audit-schedules/entities/audit-schedule-row.entity';
import { MeetingParticipant } from './meeting-participant.entity';
import { MeetingInvite } from './meeting-invite.entity';

export enum MeetingType {
  /** tied to an audit — checklist, NC drafting and evidence pack switch on */
  AUDIT = 'AUDIT',
  /** internal team call */
  INTERNAL = 'INTERNAL',
  /** sales or marketing call with a prospect */
  SALES = 'SALES',
  /** anything else */
  OTHER = 'OTHER',
}

export enum MeetingStatus {
  SCHEDULED = 'SCHEDULED',
  LIVE = 'LIVE',
  ENDED = 'ENDED',
  CANCELLED = 'CANCELLED',
}

/**
 * A meeting is generic. `audit_row_id` is nullable — when it is set the audit
 * features switch on (checklist from the standard, AI NC drafting, evidence
 * pack, and the meeting appears in that audit's history). When null it is
 * simply a call with video, chat, attendance and recording.
 *
 * Keeping this generic means Marketing and Coordinator users can hold calls on
 * the platform without an audit, which is what stops them falling back to
 * WhatsApp.
 */
@Entity('meetings')
export class Meeting {
  @PrimaryGeneratedColumn()
  id: number;

  /**
   * Human-readable, unique. Displayed on the phone and used as the socket.io
   * room name, so it must be safe to put in a URL and easy to read aloud.
   */
  @Index({ unique: true })
  @Column({ type: 'varchar', length: 40 })
  room_code: string;

  @Column({ type: 'varchar', length: 255 })
  title: string;

  @Column({ type: 'text', nullable: true })
  description: string | null;

  @Column({
    type: 'enum',
    enum: MeetingType,
    default: MeetingType.OTHER,
  })
  type: MeetingType;

  @Index()
  @Column({
    type: 'enum',
    enum: MeetingStatus,
    default: MeetingStatus.SCHEDULED,
  })
  status: MeetingStatus;

  // ── optional audit link ────────────────────────────────────────────────

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

  @ManyToOne(() => AuditScheduleRow, { nullable: true, onDelete: 'SET NULL' })
  @JoinColumn({ name: 'audit_row_id' })
  audit_row: AuditScheduleRow | null;

  /** denormalised so a meeting still names its client if the audit is deleted */
  @Index()
  @Column({ type: 'int', nullable: true })
  company_id: number | null;

  @ManyToOne(() => Company, { nullable: true, onDelete: 'SET NULL' })
  @JoinColumn({ name: 'company_id' })
  company: Company | null;

  // ── ownership ──────────────────────────────────────────────────────────

  @Index()
  @Column({ type: 'int' })
  host_user_id: number;

  @ManyToOne(() => User, { onDelete: 'RESTRICT' })
  @JoinColumn({ name: 'host_user_id' })
  host_user: User;

  // ── timing ─────────────────────────────────────────────────────────────

  @Index()
  @Column({ type: 'datetime', nullable: true })
  scheduled_at: Date | null;

  @Column({ type: 'datetime', nullable: true })
  started_at: Date | null;

  @Column({ type: 'datetime', nullable: true })
  ended_at: Date | null;

  /** filled when the last participant leaves */
  @Column({ type: 'int', nullable: true })
  duration_seconds: number | null;

  // ── evidence ───────────────────────────────────────────────────────────

  @Column({ type: 'boolean', default: true })
  is_recorded: boolean;

  @Column({ type: 'varchar', length: 500, nullable: true })
  recording_url: string | null;

  @Column({ type: 'varchar', length: 500, nullable: true })
  transcript_url: string | null;

  /**
   * Snapshot of what happened, written at the end of the call. Kept as JSON so
   * the shape can grow without a migration — questions covered, NCs confirmed,
   * documents received and so on.
   */
  @Column({ type: 'json', nullable: true })
  summary: Record<string, any> | null;

  // ── relations ──────────────────────────────────────────────────────────

  @OneToMany(() => MeetingParticipant, (p) => p.meeting)
  participants: MeetingParticipant[];

  @OneToMany(() => MeetingInvite, (i) => i.meeting)
  invites: MeetingInvite[];

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

  @CreateDateColumn()
  created_at: Date;

  @UpdateDateColumn()
  updated_at: Date;
}
