import { gracely } from "gracely"
import { http } from "cloudly-http"
import { Accounts } from "./Accounts"
import { Audit } from "./Audit"
import { Cards } from "./Cards"
import { Logs } from "./Logs"
import { Me } from "./Me"
import { Operations } from "./Operations"
import { Organizations } from "./Organizations"
import { Policies } from "./Policies"
import { Processor } from "./Processor"
import { Reports } from "./Reports"
import { Settlements } from "./Settlements"
import { Transactions as ClientTransactions } from "./Transactions"
import { Treasury } from "./Treasury"
import { Users } from "./Users"
import { Version } from "./Version"
export class Client {
	realm?: string
	organization?: string
	readonly accounts: Accounts
	readonly audits: Audit
	readonly cards: Cards
	readonly logs: Logs
	readonly policies: Policies
	readonly me: Me
	readonly operations: Operations
	readonly organizations: Organizations
	readonly processors: Processor
	readonly reports: Reports
	readonly settlements: Settlements
	readonly transactions: ClientTransactions
	readonly treasury: Treasury
	readonly users: Users
	readonly version: Version
	set key(value: string | undefined) {
		this.client.key = value
	}
	get key(): string | undefined {
		return this.client.key
	}
	set onError(value: ((request: http.Request, response: http.Response) => Promise<boolean>) | undefined) {
		this.client.onError = value
	}
	get onError(): ((request: http.Request, response: http.Response) => Promise<boolean>) | undefined {
		return this.client.onError
	}
	private constructor(private readonly client: http.Client<gracely.Error>) {
		this.client.onUnauthorized = async () => this.onUnauthorized != undefined && (await this.onUnauthorized(this))
		this.accounts = new Accounts(this.client)
		this.audits = new Audit(this.client)
		this.cards = new Cards(this.client)
		this.logs = new Logs(this.client)
		this.policies = new Policies(this.client)
		this.me = new Me(this.client)
		this.operations = new Operations(this.client)
		this.organizations = new Organizations(this.client)
		this.processors = new Processor(this.client)
		this.reports = new Reports(this.client)
		this.settlements = new Settlements(this.client)
		this.transactions = new ClientTransactions(this.client)
		this.treasury = new Treasury(this.client)
		this.users = new Users(this.client)
		this.version = new Version(this.client)
	}
	onUnauthorized?: (client: Client) => Promise<boolean>

	static create(server: string, key?: string): Client {
		const httpClient: http.Client<gracely.Error> = new http.Client<gracely.Error>(server, key, {
			appendHeader: request => ({
				...request.header,
				realm: result.realm,
				...((request.header.organization ?? result.organization)
					? { organization: request.header.organization ?? result.organization }
					: {}),
			}),
			postprocess: async response => {
				let result = response
				const body = await response.body
				if (Array.isArray(body)) {
					result = http.Response.create(
						Object.defineProperty(body, "cursor", {
							value: response.header.cursor ?? response.header.link?.split?.(",")[0],
						})
					)
				}
				return result
			},
		})
		const result: Client = new Client(httpClient)
		return result
	}
}
export namespace Client {
	export import Transactions = ClientTransactions
}
