import { Language, Markdown } from '@signatu/common-lib';
import { ConsentActionType } from '@signatu/consent';
import { PolicyDataProcessing } from '@signatu/policy';
import { Theme, WithStyles, withStyles } from '@signatu/styles';
import PropTypes from 'prop-types';
import React from 'react';

import { CONSENT_BASE_PROPTYPES, ConsentProps } from '../lib/consentBase';
import { ConsentRequest } from './consentRequest';

export interface DataProcessingConsentProps extends ConsentProps {
    /**
     * Type of consent controls - BUTTON or CHECKBOX
     *
     * @default "CHECKBOX"
     */  
    type?: ConsentActionType
    dataprocessing: PolicyDataProcessing
}

const uppercaseFirstCharacter = (s: string) => {
    return s.charAt(0).toUpperCase() + s.slice(1);
}

const styles = (theme: Theme) => ({
    root: {
        fontFamily: theme.typography.fontFamily, 
        fontWeight: theme.typography.fontWeight, 
        fontSize: theme.typography.fontSize, 
    }, 
    /** nbsp; before each of these */
    action: {
        '&:before': {
            content: '"\\00a0"'
        }
    }, 
    controller: {
    }, 
    subject: {
        '&:before': {
            content: '"\\00a0"'
        }
    }, 
    data: {
        '&:before': {
            content: '"\\00a0"'
        }
    }, 
    purpose: {
        '&:before': {
            content: '"\\00a0"'
        }
    }, 
})

class DataProcessingConsent extends React.Component<DataProcessingConsentProps & WithStyles, {}> {
    static displayName = "DataProcessingConsent"
    /** PropTypes for non-Typescript environments */
    static propTypes = {
        ...CONSENT_BASE_PROPTYPES, 
        dataprocessing: PropTypes.object as PropTypes.Validator<any>, 
        type: PropTypes.string as PropTypes.Validator<ConsentActionType | undefined>, 
        classes: PropTypes.object as PropTypes.Validator<any>
    }

    markdown = new Markdown()
    constructor(props) {
        super(props)
    }
    render() {
        const { classes, type, dataprocessing, config, subject, issuer, target, scope, delegate } = this.props
        const isoLang = this.props.language || 'en'
        const language = new Language(isoLang)
        let consentContent: any = (
        <div className={classes.root}>
            <span className={classes.controller}>{uppercaseFirstCharacter(dataprocessing.controllerText(language))}</span> 
            <span title="The type of processing" className={classes.action}> {dataprocessing.actionText(language)}</span>
            <span className={classes.subject}>{dataprocessing.subjectText(language)}</span> 
            <span title="Personal data we process" className={classes.data}>{dataprocessing.data} </span>
            <span className={classes.purpose}>{dataprocessing.purposeText(language)}</span> 
            <span 
                title="The purpose of the processing" 
                className={classes.purpose}
                dangerouslySetInnerHTML={{__html: this.markdown.html(dataprocessing.purpose)}}
            />
            </div> 
        )

        /** If the element has content for the language, use that instead */
        const content = dataprocessing.getContentForLanguage(language)
        if (content.length > 0) {
            consentContent = (
                <div className={classes.root}>
                    {content.map( (c, idx) => <div key={idx} dangerouslySetInnerHTML={{__html: this.markdown.html(c.value)}}/>)}
                </div>
            )
        }
        
        return (
        <div data-type="DataProcessingConsent">
            <ConsentRequest 
                config={config}
                language={isoLang}
                type={type}

                subject={subject}
                issuer={issuer}
                target={target}
                scope={scope}
                
                delegate={delegate}

                optOut={this.props.optOut}
            >
                {consentContent}
                {this.props.children}
            </ConsentRequest>
        </div>
    )
    }
}

const styled = withStyles<DataProcessingConsentProps>(styles)(DataProcessingConsent)
export { styled as DataProcessingConsent }
