import type convert from 'color-convert';

export type ColorLike = ColorInstance | string | ArrayLike<number> | number | Record<string, any>;
export type ColorJson = {model: string; color: number[]; valpha: number};
export type ColorObject = {alpha?: number | undefined} & Record<string, number>;

// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export interface ColorInstance {
	toString(): string;
	// eslint-disable-next-line @typescript-eslint/naming-convention
	toJSON(): ColorJson;
	string(places?: number): string;
	percentString(places?: number): string;
	array(): number[];
	object(): ColorObject;
	unitArray(): number[];
	unitObject(): {r: number; g: number; b: number; alpha?: number | undefined};
	round(places?: number): ColorInstance;
	alpha(): number;
	alpha(value: number): ColorInstance;
	red(): number;
	red(value: number): ColorInstance;
	green(): number;
	green(value: number): ColorInstance;
	blue(): number;
	blue(value: number): ColorInstance;
	hue(): number;
	hue(value: number): ColorInstance;
	saturationl(): number;
	saturationl(value: number): ColorInstance;
	lightness(): number;
	lightness(value: number): ColorInstance;
	saturationv(): number;
	saturationv(value: number): ColorInstance;
	value(): number;
	value(value: number): ColorInstance;
	chroma(): number;
	chroma(value: number): ColorInstance;
	gray(): number;
	gray(value: number): ColorInstance;
	white(): number;
	white(value: number): ColorInstance;
	wblack(): number;
	wblack(value: number): ColorInstance;
	cyan(): number;
	cyan(value: number): ColorInstance;
	magenta(): number;
	magenta(value: number): ColorInstance;
	yellow(): number;
	yellow(value: number): ColorInstance;
	black(): number;
	black(value: number): ColorInstance;
	x(): number;
	x(value: number): ColorInstance;
	y(): number;
	y(value: number): ColorInstance;
	z(): number;
	z(value: number): ColorInstance;
	l(): number;
	l(value: number): ColorInstance;
	a(): number;
	a(value: number): ColorInstance;
	b(): number;
	b(value: number): ColorInstance;
	keyword(): string;
	keyword<V extends string>(value: V): ColorInstance;
	hex(): string;
	hex<V extends string>(value: V): ColorInstance;
	hexa(): string;
	hexa<V extends string>(value: V): ColorInstance;
	rgbNumber(): number;
	luminosity(): number;
	contrast(color2: ColorInstance): number;
	level(color2: ColorInstance): 'AAA' | 'AA' | '';
	isDark(): boolean;
	isLight(): boolean;
	negate(): ColorInstance;
	lighten(ratio: number): ColorInstance;
	darken(ratio: number): ColorInstance;
	saturate(ratio: number): ColorInstance;
	desaturate(ratio: number): ColorInstance;
	whiten(ratio: number): ColorInstance;
	blacken(ratio: number): ColorInstance;
	grayscale(): ColorInstance;
	fade(ratio: number): ColorInstance;
	opaquer(ratio: number): ColorInstance;
	rotate(degrees: number): ColorInstance;
	mix(mixinColor: ColorInstance, weight?: number): ColorInstance;
	rgb(...arguments_: number[]): ColorInstance;
	hsl(...arguments_: number[]): ColorInstance;
	hsv(...arguments_: number[]): ColorInstance;
	hwb(...arguments_: number[]): ColorInstance;
	cmyk(...arguments_: number[]): ColorInstance;
	xyz(...arguments_: number[]): ColorInstance;
	lab(...arguments_: number[]): ColorInstance;
	lch(...arguments_: number[]): ColorInstance;
	ansi16(...arguments_: number[]): ColorInstance;
	ansi256(...arguments_: number[]): ColorInstance;
	hcg(...arguments_: number[]): ColorInstance;
	apple(...arguments_: number[]): ColorInstance;
}

export type ColorConstructor = {
	(object?: ColorLike, model?: keyof (typeof convert)): ColorInstance;
	new(object?: ColorLike, model?: keyof (typeof convert)): ColorInstance;
	rgb(...value: number[]): ColorInstance;
	rgb(color: ColorLike): ColorInstance;
	hsl(...value: number[]): ColorInstance;
	hsl(color: ColorLike): ColorInstance;
	hsv(...value: number[]): ColorInstance;
	hsv(color: ColorLike): ColorInstance;
	hwb(...value: number[]): ColorInstance;
	hwb(color: ColorLike): ColorInstance;
	cmyk(...value: number[]): ColorInstance;
	cmyk(color: ColorLike): ColorInstance;
	xyz(...value: number[]): ColorInstance;
	xyz(color: ColorLike): ColorInstance;
	lab(...value: number[]): ColorInstance;
	lab(color: ColorLike): ColorInstance;
	lch(...value: number[]): ColorInstance;
	lch(color: ColorLike): ColorInstance;
	ansi16(...value: number[]): ColorInstance;
	ansi16(color: ColorLike): ColorInstance;
	ansi256(...value: number[]): ColorInstance;
	ansi256(color: ColorLike): ColorInstance;
	hcg(...value: number[]): ColorInstance;
	hcg(color: ColorLike): ColorInstance;
	apple(...value: number[]): ColorInstance;
	apple(color: ColorLike): ColorInstance;
};

// eslint-disable-next-line @typescript-eslint/naming-convention
declare const Color: ColorConstructor;

export default Color;
