import { TicketFormatType } from '../order/types'
import { Address, IdParam } from '../common/types'

export enum KycLevel {
	None = 1,
	TicketHolderInfo = 2,
	PhotoIdNoFm = 3,
	PhotoIdFm = 4,
}

/**
 * Additional fields which can be included in an organizer response
 */
export type OrganizerAdditionalFields =
	| 'tos'
	| 'payment_providers'
	| 'ticket_format'
	| 'workspace'

export type UserAdditionalFields = 'permissions'

/**
 * The ID or the `name` of an organizer
 */
export interface OrganizerId {
	id: string | number
}

export interface OrganizerQuery {
	fields?: OrganizerAdditionalFields[]
}

export interface UserQuery {
	fields?: UserAdditionalFields[]
}

export interface ListUserQuery {
	email?: string
}

export interface GetOrganizerRequest extends OrganizerId, OrganizerQuery {}

/**
 * For creating a new organizer.
 *
 * @param name will be in the url and used internally, can't be changed
 * @param displayName shown to clients
 * @param organizationName blockchain tenant, umbrella organization
 * @param ownerId id of the person to be granted all permissions
 * @param kycLevelId default KYC level required on the organizer's events
 * @param ticketFormats which ticket formats are supported by default
 * @param url website of the organization
 * @param tos Terms of Service of the organizer
 */
export interface NewOrganizer extends Partial<Address> {
	name: string
	displayName?: string
	organizationName?: string
	ownerId: number
	email?: string
	phone?: string
	kycLevelId?: KycLevel
	ticketFormats?: TicketFormatType[]
	url?: string
	tos?: string
	// status?: string
	// eventTimerS?: number
}

/**
 * Organizer interface
 */
export interface Organizer {
	id: number
	name: string
	organizationName: string
	displayName: string
	url: string
	ownerId: number
	kycLevelId: KycLevel
	eventTimerS: number
	street1: string
	street2: string
	city: string
	state: string
	country: string
	zip: string
	email: string
	phone: string
	taxNumber?: string
	status?: string
	tos?: string
	workspaceKey?: string
	fees?: Fee[]
	ticketFormats?: string[]
	paymentProviders?: PaymentProviderData[]
	manuallyApproved?: boolean
	dashboardId?: string
	metaPixelId?: string
	gtmId?: string
	stripeConnectComplete?: boolean
	stripeConnectMatch?: boolean
	legalInfoComplete?: boolean
	requireStripeConnect?: boolean
	requireLegalInfo?: boolean
}
export interface PaymentProviderData {
	id: number
	orgId: number
	name: string
	providerAccId: string
}

// #region Fees
export interface Fee {
	id: number
	organizerId: number
	type: FeeType
	fixedAmount?: number
	minimumAmount?: number
	maximumAmount?: number
	percentage?: number
	currencyId: number
	taxRate?: number
	currency?: Currency
}

export enum FeeType {
	PerOrder = 0,
	PerOrderItem = 1,
	PerTicket = 2,
}

export interface Currency {
	id: number
	name: string
	acronym: string
}

export interface FeeUpdate {
	fixedAmount?: number
	minimumAmount?: number
	maximumAmount?: number
	percentage?: number
	currencyId?: number
	taxRate?: number
}

export type FeeCreate = Omit<Fee, 'id' | 'currency'>
// #endregion

// #region User
export enum Roles {
	User = 0,
	OnSiteSales = 1,
	HostOrganizer = 2,
	HostManager = 3,
	Admin = 4,
	Custom = 5,
}

export interface EnrollmentId {
	enrollmentId: string
}

export interface UserMeta extends Partial<Address> {
	firstName?: string
	lastName?: string
	dateOfBirth?: Date
	gender?: string
	phone?: string
	description?: string
	pictureUrl?: string
	paypalAccount?: string
	localeCode?: string
	firebaseToken?: string
}

export interface User extends UserMeta, IdParam {
	username: string
	email: string
	enrollmentId: string
	verified: boolean
	permissions?: CompletePermissions
	shouldRenewCertificate: boolean
}

export interface NewUser extends UserMeta {
	password: string
	username: string
	email: string
}

export type PublicUser = Pick<User, 'pictureUrl' | 'username' | 'id'>

export interface UserPermissions {
	organizationName: string
	role: Roles
	grantedPermissions?: PerOrgPermissions
}

export interface UserInviteData extends UserMeta {
	password?: string
	username?: string
	email: string
}

export interface UserInvite extends UserInviteData, UserPermissions {}

export interface UserUpdate extends UserMeta {
	password?: string
	username?: string
	email?: string
}

export interface UserPermissionChange {
	granted: CompletePermissions
	revoked: CompletePermissions
}

export interface PublicUserData {
	id: number
	username: string
	pictureUrl?: string
	enrollmentId?: string
}

export type CompletePermissions = {
	[key: string]: PerOrgPermissions
}

export type PerOrgPermissions = {
	[key: string]: string[]
}

export interface Email {
	email: string
}

export interface Password {
	password: string
}

export interface ResetPasswordCode {
	resetCode: string
}

export interface Wallet {
	id: number
	enrollmentId: string
	certificate: string
	privateKey: string
}

/**
 * Represents a workspace on seats.io.
 * It is used for creating seating charts, social distancing rules and associating events with seating charts.
 *
 * @param organizerId the number id of the organizer to which the workspace belongs to
 * @param name the name of the workspace
 * @param key the public key, used for rendering charts on the frontend
 * @param secretKey the key which is used for administration of the workspace
 * @param isTest represents if the workspace and the organizer are in test mode
 */
export interface SeatsWorkspace {
	id: number
	organizerId: number
	name: string
	key: string
	secretKey: string
	isTest: boolean
	isActive: boolean
	isDefault: boolean
}

export interface MarketRuleset {
	id: string
	name: string
	priceLimitPercentage: number
	priceLimitFixed: number
	feeFixed: number
	feePercentage: number
	transferEnabled: boolean
	resaleEnabled: boolean
	organizerId: number
	status: MarketControlStatus
}

export interface MarketRulesetCreate {
	organizerId: number
	name?: string
	priceLimitPercentage?: number
	priceLimitFixed?: number
	feeFixed?: number
	feePercentage?: number
	transferEnabled?: boolean
	resaleEnabled?: boolean
}

export interface MarketRulesetUpdate {
	name?: string
	priceLimitPercentage?: number
	priceLimitFixed?: number
	feeFixed?: number
	feePercentage?: number
	transferEnabled?: boolean
	resaleEnabled?: boolean
}

export interface ListQuery {
	sort_by?: string
	direction?: string
}

export interface MarketRulesetListQuery extends ListQuery {
	organizer_id?: number
}

export enum MarketControlStatus {
	Draft = 'draft',
	Published = 'published',
	Updated = 'updated',
}

export interface KYCLevel {
	id: number
	level: string
	displayName: string
}

export interface OnboardStripePayload {
	returnUrl: string
	refreshUrl: string
}

export interface OnboardStripeResponse {
	redirectUrl: string
}

export interface OnboardStripeStatus {
	completedOnboarding: boolean
	fullyOnboard: boolean
	canUseStripe: boolean
}

export interface OrganizerDomain {
	id: number
	organizerId: number
	name: string
	organizer?: Organizer
}

export type OrganizerDomainCreate =
	| {
			organizerId: number
			name: string
	  }
	| {
			organizerName: string
			name: string
	  }

export interface OrganizerDomainUpdate {
	name: string
}

/**
 * Query for listing organizer domains
 *
 * @param organizer_id the id or the name of the organizer
 * @param name the whole or partial domain
 */
export interface OrganizerDomainQuery extends ListQuery {
	organizer_id?: number | string
	name?: string
}

export interface NewsletterCreate {
	subject: string
	content: string
}

export type NewsletterUpdate = Partial<NewsletterCreate>

export interface Newsletter extends NewsletterCreate {
	id: number
	sentAt?: Date
}

export interface NewsletterQuery extends ListQuery {
	sort_by?: 'sentAt' | 'subject' | 'id'
}
