/**
 * Domain Entity: SponsorAccount
 * 
 * Represents a sponsor's login account in the identity bounded context.
 * Separate from the racing domain's Sponsor entity which holds business data.
 */

import { UserId } from '../value-objects/UserId';
import type { EmailValidationResult } from '../types/EmailAddress';
import { validateEmail } from '../types/EmailAddress';

export interface SponsorAccountProps {
  id: UserId;
  sponsorId: string; // Reference to racing domain's Sponsor entity
  email: string;
  passwordHash: string;
  companyName: string;
  isActive: boolean;
  createdAt: Date;
  lastLoginAt?: Date;
}

export class SponsorAccount {
  private readonly id: UserId;
  private readonly sponsorId: string;
  private email: string;
  private passwordHash: string;
  private companyName: string;
  private isActive: boolean;
  private readonly createdAt: Date;
  private lastLoginAt: Date | undefined;

  private constructor(props: SponsorAccountProps) {
    this.id = props.id;
    this.sponsorId = props.sponsorId;
    this.email = props.email;
    this.passwordHash = props.passwordHash;
    this.companyName = props.companyName;
    this.isActive = props.isActive;
    this.createdAt = props.createdAt ?? new Date();
    this.lastLoginAt = props.lastLoginAt;
  }

  public static create(props: Omit<SponsorAccountProps, 'createdAt' | 'isActive'> & {
    createdAt?: Date;
    isActive?: boolean;
  }): SponsorAccount {
    if (!props.sponsorId || !props.sponsorId.trim()) {
      throw new Error('SponsorAccount sponsorId is required');
    }

    if (!props.companyName || !props.companyName.trim()) {
      throw new Error('SponsorAccount companyName is required');
    }

    if (!props.passwordHash || !props.passwordHash.trim()) {
      throw new Error('SponsorAccount passwordHash is required');
    }

    const emailResult: EmailValidationResult = validateEmail(props.email);
    if (!emailResult.success) {
      throw new Error(emailResult.error);
    }

    return new SponsorAccount({
      ...props,
      email: emailResult.email,
      createdAt: props.createdAt ?? new Date(),
      isActive: props.isActive ?? true,
    });
  }

  public getId(): UserId {
    return this.id;
  }

  public getSponsorId(): string {
    return this.sponsorId;
  }

  public getEmail(): string {
    return this.email;
  }

  public getPasswordHash(): string {
    return this.passwordHash;
  }

  public getCompanyName(): string {
    return this.companyName;
  }

  public getIsActive(): boolean {
    return this.isActive;
  }

  public getCreatedAt(): Date {
    return this.createdAt;
  }

  public getLastLoginAt(): Date | undefined {
    return this.lastLoginAt;
  }

  public canLogin(): boolean {
    return this.isActive;
  }

  public recordLogin(): SponsorAccount {
    return new SponsorAccount({
      id: this.id,
      sponsorId: this.sponsorId,
      email: this.email,
      passwordHash: this.passwordHash,
      companyName: this.companyName,
      isActive: this.isActive,
      createdAt: this.createdAt,
      lastLoginAt: new Date(),
    });
  }

  public deactivate(): SponsorAccount {
    return new SponsorAccount({
      id: this.id,
      sponsorId: this.sponsorId,
      email: this.email,
      passwordHash: this.passwordHash,
      companyName: this.companyName,
      isActive: false,
      createdAt: this.createdAt,
      ...(this.lastLoginAt ? { lastLoginAt: this.lastLoginAt } : {}),
    });
  }

  public updatePassword(newPasswordHash: string): SponsorAccount {
    if (!newPasswordHash || !newPasswordHash.trim()) {
      throw new Error('Password hash cannot be empty');
    }

    return new SponsorAccount({
      id: this.id,
      sponsorId: this.sponsorId,
      email: this.email,
      passwordHash: newPasswordHash,
      companyName: this.companyName,
      isActive: this.isActive,
      createdAt: this.createdAt,
      ...(this.lastLoginAt ? { lastLoginAt: this.lastLoginAt } : {}),
    });
  }
}