import React, { Component } from 'react'
import { Dimensions, Image, PanResponder, View, StyleSheet, PanResponderInstance } from 'react-native'
import { TYSdk } from 'tuya-panel-kit'

import ColorUtils from '../utils/ColorUtils'
import res from '@res'

export default class ColorExtractor extends Component<any> {
    state: any
    _panResponder: PanResponderInstance
    onColorChange: any
    lastX: any
    lastY: any
    self: any
    startTouchXY: any

    constructor(props) {
        super(props)
        let {
            thumbSizeW,
            radius,
            color,
            onColorChange,
            colorTemperatureInterval,
            miniColorTemperature,
        } = !!props && props
        this.onColorChange = onColorChange
        radius = radius || 130
        thumbSizeW = thumbSizeW || 30
        const currentColor = color
        this.state = {
            thumbSizeW,
            radius,
            offset: { x: radius - thumbSizeW / 2, y: radius - thumbSizeW / 2 },
            currentColor,
            ratio: 0,
            miniColorTemperature: !!miniColorTemperature ? miniColorTemperature : 2700,
            colorTemperatureInterval: colorTemperatureInterval,
        }
        this.lastX = radius - thumbSizeW / 2
        this.lastY = radius - thumbSizeW / 2
    }

    onLayout(_: any) {

    }

    componentDidMount() {
        this.updateUIWithColor(this.state.currentColor, true)
        // 图标的手势
        this._panResponder = PanResponder.create({
            onMoveShouldSetPanResponder: () => {
                return true
            },
            onPanResponderMove: (evt, gestureState) => {
                this.handlerData(evt, gestureState, true)
            },
            onPanResponderRelease: (evt, gestureState) => {
                this.handlerData(evt, gestureState, false)
            },
        })

        if (this.props.showColorTemperature) {
            TYSdk.event.off('onColorTempChange')
            TYSdk.event.on('onColorTempChange', (color) => {
                this.updateUIWithColor(color, false)
            })
        } else {
            TYSdk.event.off('onColorChange')
            TYSdk.event.on('onColorChange', (color) => {
                this.updateUIWithColor(color, false)
            })
        }
    }

    componentWillUnmount() {
        TYSdk.event.off('onColorChange')
        TYSdk.event.off('onColorTempChange')
    }

    handleTapData(evt) {
        if (!!this.props.disabled) {
            return
        }
        let tapX = evt.nativeEvent.locationX
        let tapY = evt.nativeEvent.locationY
        let result = this.getPointValues(tapX, tapY)
        let maxX = result.maxX
        let maxY = result.maxY
        this.setState({
            offset: {
                x: maxX,
                y: maxY,
            },
        })
        this.lastX = maxX
        this.lastY = maxY
        this.updateColor(evt.nativeEvent.locationX, evt.nativeEvent.locationY, false)
    }

    handlerData(_evt, ges, moving) {
        if (!!this.props.disabled) {
            return
        }

        //此时视图的坐标
        let locationX = this.lastX + ges.dx + this.state.thumbSizeW / 2
        let locationY = this.lastY + ges.dy + this.state.thumbSizeW / 2
        // 获取在父元素的实际坐标点值
        let result = this.getPointValues(locationX, locationY)
        let maxX = result.maxX
        let maxY = result.maxY
        // 获取此点的颜色值
        this.updateColor(locationX, locationY, moving)

        this.setState({
            offset: {
                x: maxX,
                y: maxY,
            },
        })

        if (!(!!moving)) {
            // 记录滑动前 图表的位置
            this.lastX = this.state.offset.x
            this.lastY = this.state.offset.y
        }
    }

    // 获取实际坐标的 角度 坐标值 步长
    getPointValues(locationX, locationY) {
        //半径
        let radius = this.state.radius
        // 求斜边的长度
        let offsetX = Math.abs(radius - locationX)
        let offsetY = Math.abs(radius - locationY)
        let length = Math.sqrt(offsetX * offsetX + offsetY * offsetY)// 斜边长度
        //求角度
        // let angle = Math.atan2(offsetY, offsetX) * (180 / Math.PI)
        let angle = this.getPointAngle(radius - locationX, radius - locationY)
        // console.log('是否出界'+[locationX,locationY,angle])
        // 最终的坐标
        let maxX = locationX - this.state.thumbSizeW / 2//this.lastX + ges.dx
        let maxY = locationY - this.state.thumbSizeW / 2//this.lastY + ges.dy
        if (length > this.state.radius) {
            // 超出边界
            let maxOffsetX = this.state.radius * (locationX - radius) / length
            let maxOffsetY = this.state.radius * (radius - locationY) / length
            maxX = radius + maxOffsetX - this.state.thumbSizeW / 2
            maxY = radius - maxOffsetY - this.state.thumbSizeW / 2
            length = this.state.radius
        }
        return {
            angle: angle,
            maxX: maxX,
            maxY: maxY,
            length: length,
        }
    }

    getPointAngle(x, y) {
        // 此时的角度是从左边为 0°开始 顺时针 到右边为 180° 逆时针到最右边为 -180°
        let angle = Math.atan2(y, x) * (180 / Math.PI)
        // 此转换为左边 0° 顺时针转一圈为 360°
        angle = 180 - angle
        //console.log('获取角度' + angle)
        return angle
    }

    // 根据颜色值更新图标的位置 color : #ffffff
    updateUIWithColor(color, isFirst) {
        const { radius } = this.state
        // 根据初始的颜色值回去图标的坐标
        const hsv = ColorUtils.hex2Hsv(color)
        //console.log('初始值颜色' + [hsv.h, hsv.s, hsv.v])

        //角度
        let angle = 180 - hsv.h
        // 在色盘中的步长
        let length = (radius / 100) * hsv.s
        //
        const offset = this.hypotenuse(length, angle)
        const offsetX = radius - offset.x - this.state.thumbSizeW / 2
        const offsetY = radius - offset.y - this.state.thumbSizeW / 2

        this.lastX = offsetX
        this.lastY = offsetY
        this.setState({
            currentColor: color,
            offset: {
                x: offsetX,
                y: offsetY,
            },
            ratio: hsv.s / 100,
        }, () => {
            this.updateColor(offsetX + this.state.thumbSizeW / 2, offsetY + this.state.thumbSizeW / 2, false, isFirst)
        })
    }

    //已知角度和斜边，求直角边
    hypotenuse(long, angle) {
        //获得弧度
        const radian = 2 * Math.PI / 360 * angle
        return {
            x: Math.cos(radian) * long,
            y: Math.sin(radian) * long,
        }
    }

    // 根据坐标的位置 获取颜色值
    updateColor(x, y, moving, isFirst?: boolean) {
        const { angle, length } = this.getPointValues(x, y)
        //console.log('根据坐标的位置 获取颜色值', angle, maxX, maxY, length);
        let radius = length / this.state.radius
        const rad = radius > 1 ? 1 : radius
        const hsv = { h: angle, s: 100 * rad, v: 100 }
        const currentColor = ColorUtils.hsv2Hex(hsv)
        this.setState({ currentColor, ratio: rad })
        //console.log('获取当前的颜色' + [currentColor, angle])
        //滑动结束 发送当前颜色值
        if (moving === false) {
            this.onColorChange && this.onColorChange(hsv, isFirst)
        }
    }

    render() {
        const { radius, offset, ratio, miniColorTemperature, colorTemperatureInterval } = this.state
        const { x, y } = offset
        const { showColorTemperature } = this.props
        return (
            <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                <View
                    ref={node => {
                        this.self = node
                    }}
                    onLayout={nativeEvent => this.onLayout(nativeEvent)}
                    style={[{
                        height: radius * 2,
                        width: radius * 2,
                    }, this.props.style]}>

                    <View
                        style={[styles.img, {
                            height: radius * 2,
                            width: radius * 2,
                        }]}>
                        <Image
                            style={{
                                height: radius * 2,
                                width: radius * 2,
                                alignItems: 'center',
                                position: 'absolute',
                            }}
                            source={{ uri: !!showColorTemperature ? res.color_temperature_wheel : res.color_wheel }}
                            // @ts-ignore
                            onStartShouldSetResponder={(evt) => {
                                this.startTouchXY = evt.nativeEvent
                                return true
                            }}
                            onResponderMove={() => {
                                return false
                            }}
                            onResponderRelease={(evt) => {
                                const { locationX, locationY, timestamp } = !!this.startTouchXY && this.startTouchXY
                                const endLocationX = evt.nativeEvent.locationX
                                const endLocationY = evt.nativeEvent.locationY
                                const endTimestamp = evt.nativeEvent.timestamp

                                if (Math.abs(locationX - endLocationX) <= 10 && Math.abs(locationY - endLocationY) <= 10 && endTimestamp - timestamp < 500) {
                                    this.handleTapData(evt)
                                }
                            }} />
                        {<View
                            {...(this._panResponder || {}).panHandlers}
                            style={{
                                marginTop: y,
                                marginLeft: x,
                                width: this.state.thumbSizeW,
                                height: this.state.thumbSizeW,
                                position: 'absolute',
                                backgroundColor: '#ffffff',
                                elevation: !!this.props.disabled ? 0 : 3,
                                shadowOpacity: 0.15,
                                shadowRadius: 5,
                                shadowOffset: { width: 0, height: 3.5 },
                                borderRadius: this.state.thumbSizeW / 2,
                            }}>
                            {!(!!showColorTemperature) && <View
                                style={{
                                    marginTop: 3,
                                    marginLeft: 3,
                                    width: this.state.thumbSizeW - 6,
                                    height: this.state.thumbSizeW - 6,
                                    position: 'absolute',
                                    backgroundColor: this.state.currentColor,
                                    borderRadius: (this.state.thumbSizeW - 6) / 2,
                                }}>
                            </View>}

                            {!!showColorTemperature && <View
                                style={{
                                    marginTop: 3,
                                    marginLeft: 3,
                                    width: this.state.thumbSizeW - 6,
                                    height: this.state.thumbSizeW - 6,
                                    position: 'absolute',
                                    backgroundColor: colorTemperatureToColor(miniColorTemperature + ratio * colorTemperatureInterval),
                                    borderRadius: (this.state.thumbSizeW - 6) / 2,
                                }}>
                            </View>}
                        </View>}
                    </View>
                </View>
            </View>
        )
    }
}
const styles = StyleSheet.create({
    colorWheelStyle: {
        width: Dimensions.get('window').width,
    },
    coverResponder: {
        width: 260,
        height: 260,
    },
    img: {},
})

export const colorTemperature = {
    2700: '#FFDC94',
    2800: '#FFDD96',
    2900: '#FFDF9A',
    3000: '#FFE19D',
    3100: '#FFE29F',
    3200: '#FFE4A3',
    3300: '#FFE5A6',
    3400: '#FFE7A9',
    3500: '#FFE8AC',
    3600: '#FFEAAF',
    3700: '#FFECB3',
    3800: '#FFEDB6',
    3900: '#FFEFB9',
    4000: '#FFF0BB',
    4100: '#FFF2BF',
    4200: '#FFF3C2',
    4300: '#FFF5C5',
    4400: '#FFF6C8',
    4500: '#FFF8CB',
    4600: '#FFFACF',
    4700: '#FFFBD2',
    4800: '#FFFCD4',
    4900: '#FFFDD7',
    5000: '#FEFEDA',
    5100: '#FEFEDD',
    5200: '#FEFFE0',
    5300: '#FAFEE1',
    5400: '#F7FEE3',
    5500: '#F3FCE3',
    5600: '#F0FCE4',
    5700: '#EDFBE6',
    5800: '#E9FAE6',
    5900: '#E5F9E8',
    6000: '#E2F9E9',
    6100: '#DFF8EA',
    6200: '#DCF7EC',
    6300: '#D7F6EC',
    6400: '#D4F5ED',
    6500: '#D1F5EF',
}

export const colorTemperatureToColor = (temperature) => {
    const colorTemperatureValue = parseInt(`${temperature / 100}`, 10) * 100
    //console.log("colorTemperatureValue :::::: ",colorTemperatureValue,colorTemperature[`${colorTemperatureValue}`])
    return colorTemperature[colorTemperatureValue]
}