import { type UserRole, type KYCStatus } from '@prisma/client';
import { AggregateRoot } from '@modules/shared/domain/aggregate-root';
import { UserRegisteredEvent } from '../events/user-registered.event';
import { type Email } from '../value-objects/email.vo';
import { type HashedPassword } from '../value-objects/hashed-password.vo';
import { type Phone } from '../value-objects/phone.vo';

export interface UserProps {
  email: Email | null;
  phone: Phone;
  passwordHash: HashedPassword | null;
  fullName: string;
  avatarUrl: string | null;
  role: UserRole;
  kycStatus: KYCStatus;
  kycData: unknown;
  isActive: boolean;
}

export class UserEntity extends AggregateRoot<string> {
  private _email: Email | null;
  private _phone: Phone;
  private _passwordHash: HashedPassword | null;
  private _fullName: string;
  private _avatarUrl: string | null;
  private _role: UserRole;
  private _kycStatus: KYCStatus;
  private _kycData: unknown;
  private _isActive: boolean;

  constructor(id: string, props: UserProps, createdAt?: Date, updatedAt?: Date) {
    super(id, createdAt, updatedAt);
    this._email = props.email;
    this._phone = props.phone;
    this._passwordHash = props.passwordHash;
    this._fullName = props.fullName;
    this._avatarUrl = props.avatarUrl;
    this._role = props.role;
    this._kycStatus = props.kycStatus;
    this._kycData = props.kycData;
    this._isActive = props.isActive;
  }

  get email(): Email | null { return this._email; }
  get phone(): Phone { return this._phone; }
  get passwordHash(): HashedPassword | null { return this._passwordHash; }
  get fullName(): string { return this._fullName; }
  get avatarUrl(): string | null { return this._avatarUrl; }
  get role(): UserRole { return this._role; }
  get kycStatus(): KYCStatus { return this._kycStatus; }
  get kycData(): unknown { return this._kycData; }
  get isActive(): boolean { return this._isActive; }

  static createNew(
    id: string,
    phone: Phone,
    fullName: string,
    passwordHash: HashedPassword,
    email?: Email,
    role: UserRole = 'BUYER',
  ): UserEntity {
    const user = new UserEntity(id, {
      email: email ?? null,
      phone,
      passwordHash,
      fullName,
      avatarUrl: null,
      role,
      kycStatus: 'NONE',
      kycData: null,
      isActive: true,
    });

    user.addDomainEvent(new UserRegisteredEvent(id, phone.value, role));
    return user;
  }

  updateKycStatus(status: KYCStatus, kycData?: unknown): void {
    this._kycStatus = status;
    if (kycData !== undefined) this._kycData = kycData;
    this.updatedAt = new Date();
  }

  deactivate(): void {
    this._isActive = false;
    this.updatedAt = new Date();
  }

  activate(): void {
    this._isActive = true;
    this.updatedAt = new Date();
  }
}
