import { useContext } from 'react';
import { BreakpointContext } from './BreakpointProvider'
import { currentDeviceType } from '../../utils/uaParser'

export interface DeviceType {
	mobile?: boolean;
	tablet?: boolean;
	desktop?: boolean;
}

export interface OrientationType {
	landscape?: boolean
	portrait?: boolean
}

export interface Breakpoints {
	xs?: boolean
	s?: boolean
	m?: boolean
	l?: boolean
	xl?: boolean
	// greater than the width
	up?: boolean
	// less than the width
	down?: boolean
	width?: {
		min?: number
		max?: number
	}
}

export type BreakpointProps = DeviceType & Breakpoints & OrientationType

const deviceType = ['mobile', 'tablet', 'desktop']

function matchWidth(width: number, min?: number, max?: number): boolean {
	if (typeof min === 'number' && typeof max === 'number') {
		return width >= min && width <= max
	}
	if (typeof min === 'number') {
		return width >= min
	}
	if (typeof max === 'number') {
		return width <= max
	}
	return false
}

export const useBreakpoint = (props: BreakpointProps): boolean => {
	const { breakpointList, size: { orientation, ...size } } = useContext(BreakpointContext)
	let enabled: boolean

	const allKeys = Object.keys(props)

	const keysWithoutDeviceType = allKeys.filter(key => !deviceType.includes(key))
	const keysWithDeviceType = allKeys.filter(key => deviceType.includes(key))

	enabled = keysWithoutDeviceType.every(key => {
		if (typeof breakpointList[key as keyof typeof breakpointList] === 'number' && !props.width) {
			if (props.up) {
				return size.width > breakpointList[key as keyof typeof breakpointList]
			}
			if (props.down) {
				return size.width <= breakpointList[key as keyof typeof breakpointList]
			}
			return size.width === breakpointList[key as keyof typeof breakpointList]
		}
		if (key === 'width') {
			return matchWidth(size.width, props.width?.min, props.width?.max)
		}
		if (key === 'landscape' || key === 'portrait') {
			return key === orientation
		}

		return true
	}) && (keysWithDeviceType.length ? keysWithDeviceType.some(key => currentDeviceType === key) : true)

	return enabled
}
