import { Email } from "../Email";
import { Entity } from "../Entity";
import { Note } from "../Note";
import { Phone } from "../Phone";
import { Result } from "../Result";
import { UniqueID } from "../UniqueID";
import { AddressTitle } from "./AddressTitle";
import { AddressType } from "./AddressType";
import { City } from "./City";
import { Country } from "./Country";
import { PostalCode } from "./PostalCode";
import { Province } from "./Province";
import { Street } from "./Street";

export interface IGenericAddressProps {
  type: AddressType;
  title: AddressTitle;
  street: Street;
  city: City;
  province: Province;
  postalCode: PostalCode;
  country: Country;
  email: Email;
  phone: Phone;
  notes: Note;
}

export interface IGenericAddress {
  type: AddressType;

  id: UniqueID;
  title: AddressTitle;
  street: Street;
  city: City;
  province: Province;
  postalCode: PostalCode;
  country: Country;
  email: Email;
  phone: Phone;
  notes: Note;
}

export class GenericAddress<T extends IGenericAddressProps>
  extends Entity<T>
  implements IGenericAddress
{
  get title(): AddressTitle {
    return this.props.title;
  }

  get street(): Street {
    return this.props.street;
  }

  get city(): City {
    return this.props.city;
  }

  get province(): Province {
    return this.props.province;
  }

  get postalCode(): PostalCode {
    return this.props.postalCode;
  }

  get country(): Country {
    return this.props.country;
  }

  get email(): Email {
    return this.props.email;
  }

  get phone(): Phone {
    return this.props.phone;
  }

  get notes(): Note {
    return this.props.notes;
  }

  get type(): AddressType {
    return this.props.type;
  }

  public toString(): {
    type: string;
    title: string;
    street: string;
    city: string;
    province: string;
    postal_code: string;
    country: string;
    email: string;
    phone: string;
    notes: string;
  } {
    return {
      type: this.type.toString(),
      title: this.title.toString(),
      street: this.street.toString(),
      city: this.city.toString(),
      province: this.province.toString(),
      postal_code: this.postalCode.toString(),
      country: this.country.toString(),
      email: this.email.toString(),
      phone: this.phone.toString(),
      notes: this.notes.toString(),
    };
  }

  public static create(props: IGenericAddressProps, id?: UniqueID) {
    return Result.ok(new this(props, id));
  }
}
