export {}

// TODO: Change to new main color
export const STANDOUT_COLOR = '#1E84E3'

/**
 * @Method POST
 */
export const REGISTER_ENDPOINT_URL = '/dashboard/api/v1/register'

/**
 * @Method GET
 */
export const OWNER_INFORMATION_ENDPOINT_URL = '/dashboard/api/v1/owner'

/**
 * @Method GET
 */
export const GET_TEAM_ENDPOINT_URL = '/dashboard/api/v1/team'

/**
 * @Method GET
 */
export const GET_USER_PROFILE_PICTURE_URL = (
  backendBaseUrl: string,
  userId: number,
) => `${backendBaseUrl}/dashboard/api/v1/profile/picture/${userId}`

/**
 * @Method GET
 */
export const GET_PROFILE_PICTURE_URL = (backendBaseUrl: string) =>
  `${backendBaseUrl}/dashboard/api/v1/profile/picture`

/**
 * @Method POST
 */
export const OWNER_SEND_VERIFICATION_EMAIL_ENDPOINT_URL =
  '/dashboard/api/v1/mail/resend-confirm-email'

/**
 * @Method POST
 * @BodyParam {string} token
 */
export const OWNER_CONFIRM_EMAIL_ENDPOINT_URL =
  '/dashboard/api/v1/mail/confirm-email'

/**
 * @Method DELETE
 * @Code 403 - Forbidden
 * @Code 400 - Can't delete creator (is in trial)
 */
export const CREATOR_DELETE_ENDPOINT_URL = (creatorId: number) =>
  `/dashboard/api/v1/creator/${creatorId}`

/**
 * @Method GET
 * @Code 200 - Success: Returns availableLicenses[]{id, name}, creatorName
 * @Code 402 - No license available
 * @Code 208 - Already added to account
 * @Code 409 - Already added to different account
 * @Code 429 - Owner is on trial and account has been used before
 */
export const CREATOR_ADD_INFORMATION_ENDPOINT_URL = (creatorId: number) =>
  `/dashboard/api/v1/creator/${creatorId}/add`

/**
 * @Method POST
 * @BodyParam {int} licenseId
 * @BodyParam {string} browserId
 * @Code 200 - Success: Added creator to account
 * @Code 400 - Bad request
 * @Code 409 - Already added to different account
 * @Code 429 - Owner is on trial and account has been used before
 */
export const CREATOR_ADD_ENDPOINT_URL = (creatorId: number) =>
  CREATOR_ADD_INFORMATION_ENDPOINT_URL(creatorId)

/**
 * @Method GET
 */
export const OWNER_LICENSES_ENDPOINT_URL = '/dashboard/api/v1/licenses'

/**
 * @Method POST
 */
export const BILLING_PORTAL_SESSION_ENDPOINT_URL =
  '/dashboard/api/v1/billing/session/portal'

/**
 * @returns {string} URL - URL to buy a new license
 * @Method POST
 * @BodyParam {string} plan - 'basic' or 'advanced'
 * @BodyParam {string} type - 'monthly' or 'yearly'
 * @BodyParam {number} quantity
 * @BodyParam {string} successUrl
 * @BodyParam {string} cancelUrl
 */
export const BILLING_PAYMENT_SESSION_ENDPOINT_URL =
  '/dashboard/api/v1/billing/session/payment'

/**
 * @returns {string} URL - URL to manage a single license
 * @Method POST
 * @BodyParam {number} licenseId
 * @BodyParam {string} plan - 'monthly' or 'yearly'
 * @BodyParma {string} type - 'basic' or 'advanced'
 */
export const BILLING_MANAGE_SESSION_ENDPOINT_URL =
  '/dashboard/api/v1/billing/session/manage'

/**
 * @returns {string} URL - URL to get license info about a creator
 * @Method GET
 * @QueryParams {number} creatorId
 */
export const CREATOR_LICENSE_INFORMATION_ENDPOINT_URL = (
  creatorId: number,
): string => `/dashboard/api/v1/creators/${creatorId}/license`

/**
 * @returns {string} URL - URL to activate a license for a creator
 * @Method POST
 * @QueryParam {number} creatorId
 * @BodyParam {string} licenseId - ID of an existing license
 */
export const CREATOR_LICENSE_ACTIVATE_LICENSE_ENDPOINT_URL = (
  creatorId: number,
): string => `/dashboard/api/v1/creators/${creatorId}/license`

/**
 * @returns {string} URL - URL to activate a creator
 * @Method POST
 * @QueryParam {number} creatorId
 */
export const CREATOR_LICENSE_ACTIVATE_CREATOR_ENDPOINT_URL = (
  creatorId: number,
): string => `/dashboard/api/v1/creators/${creatorId}/activate`

export class LegendItem {
  label: string
  color: string | undefined

  constructor(label: string, color: string | undefined) {
    this.label = label
    this.color = color
  }
}

export class SelectOption {
  value: number
  label: string

  constructor(value: number, label: string) {
    this.value = value
    this.label = label
  }
}

export type SubscriptionPlan =
  | 'basic_monthly'
  | 'basic_yearly'
  | 'advanced_monthly'
  | 'advanced_yearly'

// TODO(ant0n7): export type SubscriptionStatus
export enum SubscriptionStatus {
  // [Modal] Dialog to activate creator
  Activatable = 'Activatable',
  // Buy more licenses to gain space to activate this creator
  NotActivatable = 'NotActivatable',

  Licensable = 'Licensable',
  // Buy more licenses to license this creator
  NotLicensable = 'NotLicensable',

  // Note: Same plan cycle available for a higher tier
  // [Modal] Dialog to upgrade creator
  Upgradeable = 'Upgradeable',
  // Note: No plan cycle available for a higher tier
  // Please tell us which creators you want to upgrade to which plan
  NotUpgradeable = 'NotUpgradeable',
}

export type SubscriptionStatusStrings = keyof typeof SubscriptionStatus

// All SubscriptionStatus strings but replace _ with space and capitalize first letter
export const SubscriptionStatusDisplayStrings = {
  [SubscriptionStatus.Activatable]: 'Click to activate',
  [SubscriptionStatus.NotActivatable]: 'Not activatable',
  [SubscriptionStatus.Licensable]: 'Click to license',
  [SubscriptionStatus.NotLicensable]: 'No licenses available',
  [SubscriptionStatus.Upgradeable]: 'Click to upgrade',
  [SubscriptionStatus.NotUpgradeable]: 'Click to upgrade',
}

export function statusToColor(status: SubscriptionStatus): string {
  switch (status) {
    case SubscriptionStatus.Activatable:
      return '#1E84E3'
    case SubscriptionStatus.NotActivatable:
      return '#F02D3A'
    case SubscriptionStatus.Licensable:
      return '#1E84E3'
    case SubscriptionStatus.NotLicensable:
      return '#F02D3A'
    case SubscriptionStatus.Upgradeable:
      return '#1E84E3'
    case SubscriptionStatus.NotUpgradeable:
      return '#1E84E3'
  }
}

export type License = {
  id: string
  quanitiy: number
  plan: SubscriptionPlan
  disabled?: boolean
  activeUsed: number
}

export class CreatorSimple {
  id: number
  name: string
  color: string = STANDOUT_COLOR
  plan: SubscriptionPlan
  status: SubscriptionStatus[]
  img?: any
  deletable?: boolean = false
  features: string[] = []
  //   'https://icon-library.com/images/no-profile-picture-icon-female/no-profile-picture-icon-female-0.jpg'

  constructor(
    id: number,
    name: string,
    status: SubscriptionStatus[],
    plan: SubscriptionPlan,
  ) {
    this.id = id
    this.name = name
    this.status = status
    this.plan = plan
  }

  static defaultImg =
    'https://icon-library.com/images/no-profile-picture-icon-female/no-profile-picture-icon-female-0.jpg'

  static loading(): CreatorSimple {
    return this.loadingWithId(0)
  }

  static loadingWithId(id: number): CreatorSimple {
    return new CreatorSimple(id, 'Loading...', [], 'basic_monthly')
  }

  static constructTotalCreator(): CreatorSimple {
    const c = new CreatorSimple(0, 'Total', [], 'advanced_yearly')
    c.features = ['stats']

    return c
  }

  planType() {
    return planToType(this.plan)
  }

  hasAccessToFeature(feature: string) {
    return this.features.includes(feature)
  }
}

export const planToType = (plan: SubscriptionPlan): string | undefined => {
  switch (plan) {
    case 'basic_monthly':
    case 'basic_yearly':
      return 'basic'
    case 'advanced_monthly':
    case 'advanced_yearly':
      return 'advanced'
    default:
      return undefined
  }
}

export type User = {
  userId: number
  name: string
  owner: true
  availableFeatures: string[]
  showOverview: boolean
  role: 'OWNER' | 'ADMIN' | 'MEMBER'
  memberId: number

  accountAge: number
  created: Date
  email: string
  profilePicture: string
  requiresNameUpdate: boolean,
  inTrial: boolean,
  trialPlanFormattedPrice: string
}

export class Owner {
  emailConfirmed: boolean
  invoiceUrls: string[]

  constructor(emailConfirmed: boolean, invoiceUrls: string[]) {
    this.emailConfirmed = emailConfirmed
    this.invoiceUrls = invoiceUrls
  }

  static loading(): Owner {
    return new Owner(true, [])
  }
}

export enum TeamMemberRole {
  Member = 'Member',
  Admin = 'Admin',
}

export enum TeamMemberStatus {
  Invited = 'Invited',
  Active = 'Active',
}

export type TeamMember = {
  id: number
  name: string
  role: TeamMemberRole
  status: TeamMemberStatus
  userId: number
  leader: boolean
  profilePicture: string
}

export class GraphElement {
  id: number
  key: string
  label: string
  color: string = STANDOUT_COLOR
  moneyRelated: boolean = true

  constructor(
    id: number,
    key: string,
    label: string,
    color?: string,
    moneyRelated?: boolean,
  ) {
    this.id = id
    this.key = key
    this.label = label

    if (color) {
      this.color = color
    }

    if (moneyRelated !== undefined) {
      this.moneyRelated = moneyRelated
    }
  }
}

export type NavItem = {
  label: string
  route: string
}

export class DataColors {
  public static colors: string[] = [
    '#9A031E',
    '#CB793A',
    '#FCDC4D',
    '#ABC8C7',
    '#F02D3A',
    '#4D685A',
  ]

  static getAndOccupyRandomColor(): string {
    const index = Math.floor(Math.random() * this.colors.length)
    return this.colors.splice(index, 1)[0]
  }

  static unoccupyColor(color: string) {
    this.colors.push(color)
  }
}

export const dateToString: (date: Date) => string = (date: Date) => {
  // date.setHours(date.getHours())
  date.setUTCHours(0, 0, 0, 0)

  return date.toISOString().split('T')[0]
}

// Turn number into currency string
export const formatCurrency: (value: number) => string = (value: number) => {
  return (
    value?.toLocaleString('en-US', {
      style: 'currency',
      currency: 'USD',
      maximumFractionDigits: 2,
    }) || '0'
  )
}

// Turn number into currency string without cents
export const formatCurrencyWithoutCents: (value: number) => string = (
  value: number,
) =>
  value?.toLocaleString('en-US', {
    style: 'currency',
    currency: 'USD',
    maximumFractionDigits: 0,
  }) || '0'

export class GraphDataset {
  label = 'All Creators'
  fill = false
  borderColor = STANDOUT_COLOR
  borderWidth = 2
  borderDash = []
  borderDashOffset = 0.0
  pointBackgroundColor = STANDOUT_COLOR
  pointBorderColor = 'rgba(255,255,255,0)'
  pointHoverBackgroundColor = '#2380f7'
  pointBorderWidth = 20
  pointHoverRadius = 3
  pointHoverBorderWidth = 15
  pointRadius = 3
  showLine = true
  data: (number | null)[] = []

  constructor(
    data: (number | null)[],
    label?: string,
    color?: string,
    fill?: boolean,
  ) {
    this.data = data

    if (label) {
      this.label = label
    }

    if (color) {
      this.borderColor = color
      this.pointBackgroundColor = color
    }

    if (fill) {
      this.fill = fill
    }
  }
}

export const validateEmailAddress: (email: string) => boolean = (
  email: string,
) => {
  // const regex = /\S+@\S+\.\S+/
  const regex =
    /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
  return regex.test(email)
}

export const validateDate: (date: string) => boolean = (date: string) => {
  const regex = /^\d{4}-\d{2}-\d{2}$/
  return regex.test(date)
}

/**
 * Turns a string into kebab case
 */
export const kebabize = (str: string) => {
  return str
    .split('')
    .map((letter, idx) => {
      return letter.toUpperCase() === letter
        ? `${idx !== 0 ? '-' : ''}${letter.toLowerCase()}`
        : letter
    })
    .join('')
}

export const isDateInPast = (d?: Date) => {
  if (!d) return false

  if (new Date(d).getTime() < new Date().getTime()) return true
}

declare global {}
