import {createLogger} from "@gongt/ts-stl-library/debug/create-logger";
import {LOG_LEVEL} from "@gongt/ts-stl-library/debug/levels";
import * as React from "react";
import {StatefulBaseComponent} from "../stateless-component";

export const prefixAll: PrefixAll = require('inline-style-prefixer/static');

export interface PrefixAll {
	(style: React.CSSProperties): React.CSSProperties;
	
	(style: CSSStyleDeclaration): CSSStyleDeclaration;
}

export interface CSSPropsMap {
	default: React.CSSProperties;
	
	[status: string]: React.CSSProperties;
}

const warn = createLogger(LOG_LEVEL.WARN, 'auto-style');

export function AutoStyle<X extends CSSPropsMap>(styleMap: X): PropertyDecorator {
	Object.keys(styleMap).forEach((key) => {
		styleMap[key] = prefixAll(styleMap[key]);
		if (key === 'default') {
			return;
		}
		styleMap[key] = Object.assign({}, styleMap.default, styleMap[key]);
	});
	return <T extends StatefulBaseComponent<any, any>>(target: T, propertyKey: string|symbol) => {
		const stateKey = 's_' + propertyKey.toString();
		if (!target.state) {
			target.state = {};
		}
		Object.defineProperty(target, propertyKey, {
			get(this: T): React.CSSProperties {
				return styleMap[this.state[stateKey] || 'default'];
			},
			set(this: T, type: keyof X) {
				if (!styleMap[type]) {
					warn('styleMap "%s.%s" do not have key "%s"', target.constructor.name, propertyKey, type);
				}
				this.setState({[stateKey]: type});
			},
		})
	};
}

export function AutoStyleProp<X extends CSSPropsMap>(styleMap: X): PropertyDecorator {
	Object.keys(styleMap).forEach((key) => {
		if (key === 'default') {
			return;
		}
		styleMap[key] = Object.assign({}, styleMap.default, styleMap[key]);
	});
	return <P, T extends StatefulBaseComponent<P, any>>(target: T, propertyKey: keyof P) => {
		const stateKey = 's_' + propertyKey.toString();
		Object.defineProperty(target, propertyKey, {
			get(this: T): React.CSSProperties {
				return styleMap[this.props[stateKey] || 'default'];
			},
		})
	};
}
