import * as React from 'react'
import { getTheme } from './selectors'
import { connect } from 'react-redux'
import {
    Shade,
    StylableComponentProps,
    StyleContext,
    Theme,
} from './interfaces'
import { object } from 'prop-types'
import * as uuid from 'uuid'

/**
 * This abstract presentational component has access
 * to the global style configuration object
 * that is made available by the StyleProvider
 */
export abstract class StylableComponent<T> extends React.Component<T, any> {

    public static contextTypes = {
        themeNotifier: object,
    }

    public id: string
    public theme: Theme

    public context: StyleContext

    constructor(props: any, state: any) {
        super(props, state)
        this.id = uuid()
        this.state = {
            hover: false,
            focus: false,
            theme: null,
        }
    }

    public componentDidMount() {
        if (!this.context.themeNotifier) {
            console.error('WARNING: Stylable component does not have access to themeNotifier')
        } else {
            // set the theme on the state
            this.setState({ theme: this.context.themeNotifier.theme })
            // console.log('SETTING THEME ON STYLABLE COMPONENT', this.state)

            // subscribe to future theme changes
            this.context.themeNotifier.subscribe(this.id, this.handleThemeUpdate)
        }
    }

    public componentWillUnmount() {
        this.context.themeNotifier.unsubscribe(this.id)
    }

    public handleThemeUpdate = (theme: Theme) => {
        this.setState({ theme })
        // console.log('HANDLE THEME UPDATE', theme, this)
    }

    public styles() {
        return (this.props as any).style
    }

    /**
     * Primary color in any shade
     */
    public primary = (shade: Shade = 500) =>
        this.state.theme
            ? this.context.themeNotifier.theme.colors.primary[shade]
            : ''

    /**
     * Secondary color in any shade
     */
    public secondary = (shade: Shade = 500) =>
        this.context.themeNotifier.theme
            ? this.context.themeNotifier.theme.colors.secondary[shade]
            : ''
    /**
     * Gray color in any shade
     */
    public gray = (shade: Shade = 500) =>
        this.context.themeNotifier.theme
            ? this.context.themeNotifier.theme.colors.gray[shade]
            : ''
    /**
     * Success color in any shade
     */
    public success = (shade: Shade = 500) =>
        this.context.themeNotifier.theme
            ? this.context.themeNotifier.theme.colors.success[shade]
            : ''
    /**
     * Warning color in any shade
     */
    public warning = (shade: Shade = 500) =>
        this.context.themeNotifier.theme
            ? this.context.themeNotifier.theme.colors.warning[shade]
            : ''
    /**
     * Error color in any shade
     */
    public error = (shade: Shade = 500) =>
        this.context.themeNotifier.theme
            ? this.context.themeNotifier.theme.colors.error[shade]
            : ''
}
