
/**
 * 主题工具
 * @author tmzdy tmui3.0
 * @description 主题样式生成工具
 * @copyright tmzdy|tmui|https://tmui.design
 */
import { colortool } from './colortool';
import { ssrRef } from '@dcloudio/uni-app'
import { cssStyleConfig, cssstyle, colorThemeType, cssDirection, linearDirection, linearDeep, linearDirectionType } from '../lib/interface';
//导入用户自定义的主题色值。
// import { theme } from '../../../theme/index';

let localTheme = {};
// #ifdef APP
try {
	localTheme = JSON.parse(uni.getStorageSync("$tmTheme"))
} catch (e) {
	//TODO handle the exception
}
// #endif
let theme = uni?.$tm?.config?.theme ? { ...uni.$tm.config.theme } : localTheme;

var colors: Array<colorThemeType> = [];
var colorObj: any = {
	red: '#FE1C00',
	pink: '#CA145D',
	purple: '#A61BC3',
	'deep-purple': '#6A0E81',
	indigo: '#652DF4',
	blue: '#0163FF',
	'light-blue': '#0889FF',
	cyan: '#11CDE8',
	teal: '#00998a',
	green: '#5DBD1F',
	'light-green': '#83D54A',
	lime: '#D4ED00',
	yellow: '#FFC400',
	amber: '#FFFB01',
	orange: '#FEA600',
	'deep-orange': '#FE5C00',
	brown: '#795548',
	'blue-grey': '#607D8B',
	grey: '#9E9E9E',
	black: '#000000',
	white: '#FFFFFF',
	primary: '#0163FF',
	'grey-5': '#fafafa',
	'grey-4': '#f5f5f5',
	'grey-3': '#eeeeee',
	'grey-2': '#e0e0e0',
	'grey-1': '#bdbdbd',
	'grey-darken-1': '#757575',
	'grey-darken-2': '#616161',
	'grey-darken-3': '#404044',
	'grey-darken-4': '#202022',
	'grey-darken-5': '#111112',
	'grey-darken-6': '#0A0A0B',
	...theme
};
for (const key in colorObj) {
	if (Object.prototype.hasOwnProperty.call(colorObj, key)) {
		const element: string = String(colorObj[key]);
		if (isCssColor(element)) {
			let rgba = colortool.cssToRgba(element);
			colors.push({
				name: key,
				value: element,
				hsva: colortool.rgbaToHsva(colortool.cssToRgba(element)),
				rgba: colortool.cssToRgba(element),
				hsla: colortool.rgbaToHsla(rgba),
				csscolor: `rgba(${rgba.r},${rgba.g},${rgba.b},${rgba.a})`
			});
		}
	}
}

function isCssColor(color: string) {
	const reg1 = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
	const reg2 = /^(rgb|RGB|rgba|RGBA)/;
	return reg1.test(color) || reg2.test(color);
}
function getColor(colorName: string) {
	let isHand: number = colors.findIndex(function (el, index) {
		return el.name == colorName;
	});
	if (isHand == -1) {
		colorName = "primary";
		isHand = colors.findIndex(function (el, index) {
			return el.name == colorName;
		});
		console.warn('主题中不存在相关名称的主题。');
	}


	return colors[isHand];
}
class themeColors {
	colors: Array<colorThemeType> = [];
	constructor(c: Array<colorThemeType> = colors) {
		this.colors = c;
	}
	public hasColors(colorName: string = "") {
		let isHand: Array<colorThemeType> = this.colors.filter(function (el, index) {
			return el.name == colorName;
		});
		return isHand.length > 0;
	}
	public add(colorName: string = "", value: string = "") {
		let isHand: Array<colorThemeType> = this.colors.filter(function (el, index) {
			return el.name == colorName;
		});
		if (isHand.length > 0) {
			// console.error('已存在相关颜色名称!!!');
			return this.colors;
		}
		if (!value) {
			console.error('颜色值必填!!!');
			return this.colors;
		}
		let rgba = colortool.cssToRgba(value);
		let color: colorThemeType = {
			csscolor: "",
			hsva: { h: 0, s: 0, v: 0, a: 0 },
			hsla: { h: 0, s: 0, l: 0, a: 0 },
			rgba: { r: 0, g: 0, b: 0, a: 0 },
			name: colorName, value: value
		};
		color.csscolor = colortool.rgbaToCss(rgba);
		color.hsva = colortool.rgbaToHsva(rgba);
		color.rgba = rgba;
		color.hsla = colortool.rgbaToHsla(rgba);
		this.colors.push(color);

		return this.colors;
	}
	public del(colorName: string) {
		let isHand: number = this.colors.findIndex(function (el, index) {
			return el.name == colorName;
		});
		if (isHand == -1) {
			console.error('删除失败，主题中不存在相关名称的主题。');
			return;
		}
		this.colors.splice(isHand, 1);
	}
	public getColor(colorName: string): colorThemeType {
		let isHand: number = this.colors.findIndex(function (el, index) {
			return el.name == colorName;
		});
		if (isHand == -1) {
			colorName = "primary";
			isHand = this.colors.findIndex(function (el, index) {
				return el.name == colorName;
			});
			console.error('主题中不存在相关名称的主题。');
		}


		return this.colors[isHand];
	}
	/**
	 * 计算主题
	 * @author tmui3.0|tmzdy
	 * @param config 样式的细化
	 * @returns cssstyle 返回一个计算好的主题系。
	 */
	public getTheme(config: cssStyleConfig = { colorname: 'primary', dark: false }): cssstyle {
		if (!config['colorname']) {
			console.error('颜色名称必填');
			config.colorname = 'primary';
		}
		let index = this.colors.findIndex(el => el.name == config.colorname);
		if (index == -1) {
			console.error('主题不存在，默认为primary');
			config.colorname = 'primary';
		}

		//当前颜色对象。
		let nowColor = { ...this.colors[index] };
		config.borderWidth = isNaN(parseInt(String(config['borderWidth']))) ? 0 : config['borderWidth'] ?? 0;
		config.borderStyle = config['borderStyle'] ? config['borderStyle'] : 'solid';
		config.borderColor = config['borderColor'] || '';
		config.borderDirection = config['borderDirection'] || cssDirection.all;
		config.linearDirection = config['linearDirection'] || linearDirection.none;
		config.linearDeep = config['linearDeep'] || linearDeep.light;
		config.shadow = isNaN(parseInt(String(config['shadow']))) ? 6 : config['shadow'];
		config.round = isNaN(parseInt(String(config['round']))) ? 4 : config['round'];
		config.opaticy = isNaN(parseInt(String(config['opaticy']))) ? 1 : config['opaticy'];
		config.outlined = typeof config['outlined'] == 'boolean' ? config['outlined'] : false;
		config.text = typeof config['text'] == 'boolean' ? config['text'] : false;
		config.blur = typeof config['blur'] == 'boolean' ? config['blur'] : false;
		// 确定一个颜色值是明亮的还是深色的,
		//以方便确定文本颜色是亮还是深来区别,否则颜色看不清.
		function isDarkColorFun(r: number, g: number, b: number) {
			const yiq = (r * 2126 + g * 7152 + b * 722) / 10000;
			return yiq < 180;
		}
		/**是否是黑色 */
		let isBlack = false;
		/**是否是白色 */
		let isWhite = false;
		/**黑或者白 */
		let isBlackAndWhite = false;
		/**是否是灰色 */
		let isGrey = false
		/**该颜色在人眼中属于深，还是浅，以适配文本色 */
		let isDarkColor = false;

		isDarkColor = isDarkColorFun(nowColor.rgba.r, nowColor.rgba.g, nowColor.rgba.b)
		//黑
		if (nowColor.hsla.h == 0 && nowColor.hsla.s == 0 && nowColor.hsla.l == 0) {
			isBlack = true;
		}
		//白
		if (nowColor.hsla.h == 0 && nowColor.hsla.s == 0 && nowColor.hsla.l == 100) {
			isWhite = true;
		}
		//灰
		if (nowColor.hsla.h == 0 && nowColor.hsla.s == 0 && nowColor.hsla.l < 100) {
			isGrey = true;
		}
		//黑或者白
		if (nowColor.hsla.h == 0 && nowColor.hsla.s == 0) {
			isBlackAndWhite = true;
		}

		let css: cssstyle = {};
		css.color = nowColor.value;
		css.config = { ...config };
		css.isBlackAndWhite = isBlackAndWhite;
		css.gradientColor = []
		css.colorname = config.colorname;
		let borderhsl = { ...nowColor.hsla };
		let borderDir = "all";
		css.borderCss = {};

		//背景颜色。
		let bghsl = { ...nowColor.hsla };
		/**非黑非白,h,s不变，只要降10%的亮度即可。 */
		if (config.dark && !isBlackAndWhite) {
			bghsl.l = 40;
		}
		if (config.blur) {
			bghsl.a = 0.85
		}
		css.backgroundColor = colortool.rgbaToCss(colortool.hslaToRgba({ ...bghsl }));

		if (isBlackAndWhite && config.dark) {
			css.backgroundColor = colortool.rgbaToCss(colortool.hslaToRgba({ ...bghsl, h: 240, s: 3, l: 8 }));
			css.border = colortool.rgbaToCss(colortool.hslaToRgba({ ...borderhsl, h: 240, s: 3, l: 12 }));
		}
		if (isWhite && !config.dark) {
			css.border = colortool.rgbaToCss(colortool.hslaToRgba({ ...borderhsl, l: 90 }));
		}
		if (isBlack && !config.dark) {
			css.border = colortool.rgbaToCss(colortool.hslaToRgba({ ...borderhsl, l: 12 }));
		}
		css.backgroundColorCss = { 'background-color': css.backgroundColor }
		//文字颜色。
		let txcolor = { ...nowColor.hsla };
		//当亮度小于（含）50需要降低文本颜色的亮度，即加深。，否则加亮，即变浅色。
		if (config.dark) {
			txcolor.l = 95;
		} else {
			if (isDarkColor) {
				txcolor.l = 95;
			} else {
				if (isGrey) {
					txcolor.l = 10;
				} else {
					txcolor.l = 20;
				}
			}
		}

		//外边框轮廓时
		//outlined
		if (config.outlined) {
			txcolor.l = nowColor.hsla.l;
			if (config.dark) {
				txcolor.l = 55;
			} else {
				if (nowColor.hsla.h != 0 && nowColor.hsla.s != 0 && !isDarkColorFun(nowColor.rgba.r, nowColor.rgba.g, nowColor.rgba.b)) {
					txcolor.l = 20;
				}
			}
			if ((isBlack || isWhite) && config.dark) {
				txcolor.l = 100
			}
			config.borderWidth = config['borderWidth'] || 2;
			let n_hsl = { h: nowColor.hsla.h, s: nowColor.hsla.s, l: 0, a: 0 };
			let o_bgcss = colortool.rgbaToCss(colortool.hslaToRgba(n_hsl));
			css.backgroundColor = o_bgcss;
			css.backgroundColorCss = { 'background-color': o_bgcss }
			css.textColor = colortool.rgbaToCss(colortool.hslaToRgba(txcolor));
		}

		//text
		if (config.text) {
			txcolor.l = nowColor.hsla.l;
			if (isGrey) {
				txcolor.l = 15;
			} else {
				// txcolor.l = 55;
				if (nowColor.hsla.h != 0 && nowColor.hsla.s != 0 && !isDarkColorFun(nowColor.rgba.r, nowColor.rgba.g, nowColor.rgba.b)) {
					txcolor.l = 20;
				}

			}
			if (config.dark) {
				txcolor.l = 60;
				if (!isBlackAndWhite) {
					txcolor.s = 100;
				}
			}
			if (isBlack) {
				txcolor.l = 90
			}
			if (isWhite) {
				txcolor.l = 15
			}
			if (nowColor.hsla.h == 0 && nowColor.hsla.s == 0 && config.dark) {
				txcolor.l = 90;
			}


			css.textColor = colortool.rgbaToCss(colortool.hslaToRgba(txcolor));
			css.border = css.textColor;
			let o_now_bgColor = nowColor.csscolor;
			let n_hsl = { h: nowColor.hsla.h, s: nowColor.hsla.s, l: 96, a: nowColor.hsla.a };
			if (config.dark) {
				if (nowColor.hsla.h != 0 && nowColor.hsla.s != 0) {
					n_hsl.l = 12;
					n_hsl.s = 35;
				} else {
					n_hsl.l = 12;
					n_hsl.s = 0;
				}

			}
			if (config.blur) {
				n_hsl.a = 0.85
			}
			o_now_bgColor = colortool.rgbaToCss(colortool.hslaToRgba(n_hsl));

			css.backgroundColor = o_now_bgColor;
			css.backgroundColorCss = { 'background-color': o_now_bgColor }
		}

		//shadow
		if (config.shadow) {
			let n_hsl = { h: nowColor.hsla.h, s: 100, l: 50, a: 0.2 };
			if (nowColor.hsla.h == 0 && nowColor.hsla.s == 0) {
				//黑白要反转。
				n_hsl = { h: 0, s: 0, l: 20, a: 0.07 };
			}
			let o_bgcss = colortool.rgbaToCss(colortool.hslaToRgba(n_hsl));
			css.shadowColor = {
				boxShadow: `0rpx ${config.shadow * 2.5}rpx ${config.shadow * 6}rpx ${o_bgcss}`
			}
		}



		//处理渐变色
		if (config.linearDirection) {

			let liner_color_1 = { h: 0, s: 0, l: 0, a: nowColor.hsla.a };
			let liner_color_2 = { h: 0, s: 0, l: 0, a: nowColor.hsla.a };
			let dir_str = linearDirection[config.linearDirection];
			// 增减控制参数。
			let addling = 0;
			if (nowColor.hsla.h < 180 && nowColor.hsla.h > 0) {
				addling = 20
			} else {
				addling = -37
			}


			//先计算渐变的亮色系。
			// 先算白或者黑
			// 如果是白
			if (nowColor.hsla.h == 0 && nowColor.hsla.s == 0 && nowColor.hsla.l == 100) {
				//白。
				if (config.linearDeep == 'light') {
					liner_color_1.l = 80;
					liner_color_2.l = 20;
				} else {
					liner_color_1.l = 50;
					liner_color_2.l = 40;
				}
			} else if (nowColor.hsla.h == 0 && nowColor.hsla.s == 0 && nowColor.hsla.l == 0) {
				//黑。
				if (config.linearDeep == 'light') {
					liner_color_1.l = 40;
					liner_color_2.l = 10;
				} else {
					liner_color_1.l = 30;
					liner_color_2.l = 0;
				}

			} else {
				liner_color_2.h = nowColor.hsla.h;
				liner_color_2.s = nowColor.hsla.s;

				liner_color_1.h = nowColor.hsla.h;
				liner_color_1.s = nowColor.hsla.s;
				if (config.linearDeep == 'light') {
					liner_color_1.h = liner_color_1.h;//色相需要往前偏移加强色系
					liner_color_1.s = 90;//饱和度需要加强
					liner_color_1.l = 70;
					liner_color_2.l = 44;

				} else if (config.linearDeep == 'dark') {

					liner_color_2.s = 90;
					liner_color_2.l = 26;

					liner_color_1.s = 90;
					liner_color_1.l = 50;
				} else if (config.linearDeep == 'accent') {
					liner_color_1.h -= 0;//色相需要往前偏移加强色系
					liner_color_1.s = 90;//饱和度需要加强
					liner_color_1.l = 54;

					liner_color_2.h -= addling;//偏移30度的色相搭配色进行渐变
					liner_color_2.s = 90;//饱和度需要加强
					liner_color_2.l = 54;
				}

			}
			if (config.dark) {
				liner_color_1.l = 40
				liner_color_2.l = 40
				txcolor.l = 90;
			}
			// 背景颜色取中间。
			let color_t_1 = colortool.rgbaToCss(colortool.hslaToRgba(liner_color_1));
			let color_t_2 = colortool.rgbaToCss(colortool.hslaToRgba(liner_color_2));
			if (!config.text && !config.outlined) {
				css.backgroundColorCss = { 'background-image': `linear-gradient(${dir_str},${color_t_1},${color_t_2})` }
				let newBgcolor = {
					h: (liner_color_1.h + liner_color_2.h) / 2,
					s: (liner_color_1.s + liner_color_2.s) / 2,
					l: (liner_color_1.l + liner_color_2.l) / 2,
					a: (liner_color_1.a + liner_color_2.a) / 2
				}
				let newBgcolorRgb = colortool.hslaToRgba(newBgcolor)

				if (!config.dark) {
					if (!isDarkColorFun(newBgcolorRgb.r, newBgcolorRgb.g, newBgcolorRgb.b) && nowColor.hsla.h != 0 && nowColor.hsla.s != 0) {
						txcolor.l = 20;
					}
				}
				css.backgroundColor = colortool.rgbaToCss(colortool.hslaToRgba(newBgcolor));
				css.gradientColor = [color_t_1, color_t_2]
				css.linearDirectionStr = dir_str;
			}

		}

		if (config.dark == true) {
			// css.cardcolor = '#0A0A0B'; //项目
			// css.inputcolor = '#111112';//输入框，表单等
			// css.bodycolor = 'rgba(5,5,5, 1.0)';//背景
			// css.disablecolor = 'rgba(30, 30, 30, 1.0)';//禁用的项目或者表单
			// css.textDisableColor = 'rgba(100, 100, 100, 1.0)';//文本禁用色.
			css = { ...css, ...uni.$tm.config?.themeConfig?.dark ?? {} }
		}

		css.textColor = colortool.rgbaToCss(colortool.hslaToRgba(txcolor));
		if (config.dark) {

			if (nowColor.hsla.h == 0 && nowColor.hsla.s == 0) {
				css.border = colortool.rgbaToCss(colortool.hslaToRgba({ ...nowColor.hsla, l: 12 }));
			} else {
				css.border = colortool.rgbaToCss(colortool.hslaToRgba({ ...nowColor.hsla, l: bghsl.l + 10 }));
			}
		} else {

			if (nowColor.hsla.h == 0 && nowColor.hsla.s == 0) {
				css.border = colortool.rgbaToCss(colortool.hslaToRgba({ ...nowColor.hsla, l: 90 }));
			} else {
				// text时,使用浅色线条,outlined时与颜色相同
				if ((config.text && config.outlined)) {
					css.border = colortool.rgbaToCss(colortool.hslaToRgba({ ...nowColor.hsla, l: 90 }));
				} else if (!config.text && config.outlined) {
					css.border = colortool.rgbaToCss(colortool.hslaToRgba({ ...txcolor }));
				} else if (!config.text && !config.outlined && config.borderWidth > 0) {
					css.border = colortool.rgbaToCss(colortool.hslaToRgba({ ...nowColor.hsla, l: bghsl.l - 3 }));
				}

			}
			css.border = config.borderColor || css.border
		}

		//设置边线样式。
		let bcss = `${config.borderWidth}rpx ${config.borderStyle} ${css.border}`;
		if (config.borderDirection == 'all') {
			css.borderCss[`border`] = bcss;
		} else if (config.borderDirection == 'x' || config.borderDirection == "leftright") {
			css.borderCss[`border-left`] = bcss;
			css.borderCss[`border-right`] = bcss;
		} else if (config.borderDirection == 'y' || config.borderDirection == "topbottom") {
			css.borderCss[`border-top`] = bcss;
			css.borderCss[`border-bottom`] = bcss;
		} else if (config.borderDirection == 'bottomleft') {
			css.borderCss[`border-left`] = bcss;
			css.borderCss[`border-bottom`] = bcss;
		} else if (config.borderDirection == 'bottomright') {
			css.borderCss[`border-right`] = bcss;
			css.borderCss[`border-bottom`] = bcss;
		} else if (config.borderDirection == 'topleft') {
			css.borderCss[`border-left`] = bcss;
			css.borderCss[`border-top`] = bcss;
		} else if (config.borderDirection == 'topright') {
			css.borderCss[`border-right`] = bcss;
			css.borderCss[`border-top`] = bcss;
		} else {
			let str = '-' + config.borderDirection;
			css.borderCss[`border${str}`] = bcss;
		}

		return css;
	}
}

export default {
	isCssColor,
	themeColors,
	getColor
};
