/**
 * User Entity
 * Usuarios del sistema con autenticacion y permisos
 * Compatible con erp-core user.entity
 *
 * @module Auth
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  Index,
  ManyToOne,
  ManyToMany,
  JoinColumn,
  JoinTable,
  OneToMany,
} from 'typeorm';
import { Tenant } from '../../core/entities/tenant.entity';
import { Role } from './role.entity';
import { Company } from './company.entity';
import { Session } from './session.entity';
import { PasswordReset } from './password-reset.entity';

export enum UserStatus {
  ACTIVE = 'active',
  INACTIVE = 'inactive',
  SUSPENDED = 'suspended',
  PENDING_VERIFICATION = 'pending_verification',
}

@Entity({ schema: 'auth', name: 'users' })
@Index('idx_users_tenant_id', ['tenantId'])
@Index('idx_users_email', ['email'])
@Index('idx_users_status', ['status'], { where: 'deleted_at IS NULL' })
@Index('idx_users_email_tenant', ['tenantId', 'email'])
@Index('idx_users_created_at', ['createdAt'])
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ type: 'uuid', nullable: false, name: 'tenant_id' })
  tenantId: string;

  @Column({ type: 'varchar', length: 255, nullable: false })
  email: string;

  @Column({ type: 'varchar', length: 255, nullable: false, name: 'password_hash' })
  passwordHash: string;

  @Column({ type: 'varchar', length: 255, nullable: false, name: 'full_name' })
  fullName: string;

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

  @Column({
    type: 'enum',
    enum: UserStatus,
    default: UserStatus.ACTIVE,
    nullable: false,
  })
  status: UserStatus;

  @Column({ type: 'boolean', default: false, nullable: false, name: 'is_superuser' })
  isSuperuser: boolean;

  @Column({ name: 'is_superadmin', default: false })
  isSuperadmin: boolean;

  @Column({ name: 'mfa_enabled', default: false })
  mfaEnabled: boolean;

  @Column({ name: 'mfa_secret_encrypted', type: 'text', nullable: true })
  mfaSecretEncrypted: string;

  @Column({ name: 'mfa_backup_codes', type: 'text', array: true, nullable: true })
  mfaBackupCodes: string[];

  @Column({ name: 'oauth_provider', length: 50, nullable: true })
  oauthProvider: string;

  @Column({ name: 'oauth_provider_id', length: 255, nullable: true })
  oauthProviderId: string;

  @Column({
    type: 'timestamp',
    nullable: true,
    name: 'email_verified_at',
  })
  emailVerifiedAt: Date | null;

  @Column({ type: 'timestamp', nullable: true, name: 'last_login_at' })
  lastLoginAt: Date | null;

  @Column({ type: 'inet', nullable: true, name: 'last_login_ip' })
  lastLoginIp: string | null;

  @Column({ type: 'integer', default: 0, name: 'login_count' })
  loginCount: number;

  @Column({ type: 'varchar', length: 10, default: 'es' })
  language: string;

  @Column({ type: 'varchar', length: 50, default: 'America/Mexico_City' })
  timezone: string;

  @Column({ type: 'jsonb', default: {} })
  settings: Record<string, any>;

  // Relaciones
  @ManyToOne(() => Tenant, (tenant) => tenant.users, {
    onDelete: 'CASCADE',
  })
  @JoinColumn({ name: 'tenant_id' })
  tenant: Tenant;

  @ManyToMany(() => Role, (role) => role.users)
  @JoinTable({
    name: 'user_roles',
    schema: 'auth',
    joinColumn: { name: 'user_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'role_id', referencedColumnName: 'id' },
  })
  roles: Role[];

  @ManyToMany(() => Company, (company) => company.users)
  @JoinTable({
    name: 'user_companies',
    schema: 'auth',
    joinColumn: { name: 'user_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'company_id', referencedColumnName: 'id' },
  })
  companies: Company[];

  @OneToMany(() => Session, (session) => session.user)
  sessions: Session[];

  @OneToMany(() => PasswordReset, (passwordReset) => passwordReset.user)
  passwordResets: PasswordReset[];

  // Auditoria
  @CreateDateColumn({ name: 'created_at', type: 'timestamp' })
  createdAt: Date;

  @Column({ type: 'uuid', nullable: true, name: 'created_by' })
  createdBy: string | null;

  @UpdateDateColumn({
    name: 'updated_at',
    type: 'timestamp',
    nullable: true,
  })
  updatedAt: Date | null;

  @Column({ type: 'uuid', nullable: true, name: 'updated_by' })
  updatedBy: string | null;

  @Column({ type: 'timestamp', nullable: true, name: 'deleted_at' })
  deletedAt: Date | null;

  @Column({ type: 'uuid', nullable: true, name: 'deleted_by' })
  deletedBy: string | null;
}
