import { Component } from "react";
import Styles from '../styles/Components/card.module.css';
import react from 'react'
import { withRouter } from "next/router";
import handleViewport from 'react-in-viewport';

class Card extends Component {
    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick(e) {
        e.preventDefault();
        if (this.props.url) {
            window.location = this.props.url;
        }
    }

    getButtonRow() {
        return this.props.buttons ? this.props.buttons.map((button, i) => {
            return <a
                key={i}
                className={Styles.button}
                style={{backgroundColor:`#${button.color}`, color:`#${this.props.buttonText}`}}
                href={button.link ? button.link : null}
                onClick={button.onClick ? button.onClick : null}
                target={button.newTab ? "_blank" : undefined}
                rel="noreferrer">{button.text}
            </a>
        }) : null
    }

    getTitleBlock() {
        let icons = null;
        if (this.props.icon && this.props.icon[0].length > 1) {
            icons = <div className={Styles.iconRow}>{this.props.icon.map((icon, i) => {
                return <img key={i} alt={this.props.title} className={Styles.image} src={`https://assets.clicks.codes/${icon}.svg`} />
            })}</div>
        } else if (this.props.icon) {
            icons = <img alt={this.props.title} className={Styles.image} src={`https://assets.clicks.codes/${this.props.icon}.svg`} />
        } else if (this.props.wave) {
            icons = <img alt={this.props.title} className={Styles.image} src={`https://assets.clicks.codes//${this.props.wave}.svg`} />
        }
        return <>{icons}</>;
    }
    getBand() {
        if (this.props.band) {
            return <div className={Styles.band} style={{
                backgroundColor: `#${this.props.band.color ?? "F27878"}`,
                bottom: this.props.buttons ? `calc(25% + 5px)` : "40px"
            }}>
                <p style={{color: "#" + (this.props.band.textColor ?? "FFFFFF")}}>{this.props.band.text ?? ""}</p>
            </div>
        }
    }

    render() {
        let overwriteAlign = {
            "left": "flex-start",
            "center": "center",
            "right": "flex-end"
        }[this.props.overwritePosition ?? "right"];
        if (this.props.border) {
            return (
                <div className={Styles.card + " " + (this.props.shown ? Styles.shown : null) + " " + Styles.dashed} style={{
                    margin: "0", opacity: `0`, boxShadow: "none", borderColor: `#${this.props.border}`
                }}>
                    <div className={Styles.noPanel}>
                        <div className={Styles.titleContainer}>
                            {
                                (this.props.icon || this.props.wave)
                                ? <img alt="Project icon" className={Styles.image} src={"https://assets.clicks.codes/" + (this.props.icon ? this.props.icon : this.props.wave) + ".svg"} />
                                : null
                            }
                            <h1 className={Styles.title}>{this.props.title}</h1>
                        </div>
                        <p className={Styles.subtext + " " + (this.props.buttons ? null : Styles.longText)}>{this.props.subtext}</p>
                        {this.getBand()}
                        <div className={Styles.buttonLayout} onClick={this.showMessage} style={{
                            justifyContent: overwriteAlign
                        }}>
                            {this.getButtonRow()}
                        </div>
                    </div>
                </div>
            );
        } else {
            return (
                <div className={Styles.card + " " + (this.props.shown ? Styles.shown : null)} style={{
                    margin: "0"
                }} onClick={this.handleClick}>
                    <div className={Styles.backgroundGradient} style={{
                        backgroundImage: `linear-gradient(69.44deg, #${this.props.gradient[0]} 0%, #${this.props.gradient[1]} 100%)`
                    }} />
                    <img alt="" className={Styles.backgroundImage} src={`https://assets.clicks.codes/web/waves/card/${this.props.wave}.svg`} draggable={false} />
                    <div className={Styles.panel} onClick={this.handleClick}>
                        <div className={Styles.titleContainer}>
                            { this.getTitleBlock() }
                            <h1 className={Styles.title}>{this.props.title}</h1>
                        </div>
                        <p className={Styles.subtext + " " + (this.props.buttons ? null : Styles.longText)}>{this.props.subtext}</p>
                        {this.getBand()}
                        <div className={Styles.buttonLayout} onClick={this.showMessage} style={{
                            justifyContent: overwriteAlign
                        }}>
                            {this.getButtonRow()}
                        </div>
                    </div>
                </div>
            );
        }
    }
}

class CardRowClass extends Component {
    constructor(props) {
        super(props);
        this.state = {
            shown: false,
            childrenShown: Array(this.props.children.length)
        }
    }

    animate() {
        const { inViewport } = this.props;
        if (inViewport) {
            this.setState({shown: true});
            for (let index = 0; index < this.state.childrenShown.length; index++) {
                setTimeout(() => {
                    this.setState(state => {
                        let childrenShown = [...state.childrenShown];
                        childrenShown[index] = true;
                        return {childrenShown};
                    })
                }, 200 * index);
            }
        }
    }

    render() {
        if (!this.props.shown) this.animate()
        return (
            <div className={Styles.container}>
                {
                    react.Children.toArray(this.props.children).map((item, index) => {
                        item = <Card
                            shown={this.state.childrenShown[index]}
                            {...item.props}
                        />
                        return <div className={Styles.item} key={index}>{item}</div>
                    })
                }
            </div>
        )
    }
}

Card = withRouter(Card);
const CardRow = handleViewport(CardRowClass, { rootMargin: '-1.0px' });

export { Card, CardRow };
