from plotly import graph_objs as go
from stats.acquisition import users_per_period


def plot_users_per_period(events, acquisition_event_name, user_source_col, period='w'):
    """
    Function use to create multi-axes plot and table for all the stats generated by
    "stats.retention.users_per_period"


    :param events: (DataFrame)
                    events dataframe

    :param acquisition_event_name: (str)
                        event name defining the user acquisition point

    :param user_source_col: (str)
                        name of column defining if user is an Organic/Non-organic acquisition

    :param period: (str)
                    str denoting period for cohort breakdown.
                    Use 'd' for daily, 'w' for weekly or 'm' for monthly

    :return: (fig)
                    plotly figure
    """

    # generate user stats per period
    df = users_per_period(events, acquisition_event_name, user_source_col, period)

    # needed to convert the month period to time_manipulations
    if period == 'm':
        df.index = df.index.to_timestamp().strftime("%Y-%m")

    # new users
    new1 = go.Bar(
        x=df.index,
        y=df['New Users (Total)'].values,
        text=df['New Users (Total)'].values,
        textposition='auto',
        marker=dict(
            color='rgb(0,0,204)'),
        name='New Users(Total)',
        xaxis='x1',
        yaxis='y1'
    )

    # new users for 2nd axis
    new2 = go.Bar(
        x=df.index,
        y=df['New Users (Total)'].values,
        text=df['New Users (Total)'].values,
        textposition='auto',
        marker=dict(
            color='rgb(0,0,204)'),
        name='New Users(Total)',
        xaxis='x1',
        yaxis='y2'
    )

    # organic users
    organic = go.Bar(
        x=df.index,
        y=df['New Organic Users'].values,
        text=df['New Organic Users'].values,
        textposition='auto',
        xaxis='x1',
        yaxis='y1',
        marker=dict(
            color='rgb(58,193,0)'),
        name='New Organic Users'
    )

    # paid users
    non_organic = go.Bar(
        x=df.index,
        y=df['New Paid Users'].values,
        text=df['New Paid Users'].values,
        textposition='auto',
        xaxis='x1',
        yaxis='y1',
        marker=dict(
            color='rgb(255,0,0)'),
        name='New Paid Users'
    )

    # active users
    active = go.Bar(
        x=df.index,
        y=df['Active Users'].values,
        text=df['Active Users'].values,
        textposition='auto',
        name='Active Users',
        xaxis='x1',
        yaxis='y2',
        marker=dict(
            color='rgb(153,0,76)')
    )

    # returning users
    returning = go.Bar(
        x=df.index,
        y=df['Returning Users'].values,
        text=df['Returning Users'].values,
        textposition='auto',
        name='Returning Users',
        xaxis='x1',
        yaxis='y2',
        marker=dict(
            color='rgb(255,128,0)')
    )

    # periodic growth
    growth = go.Scatter(
        x=df.index,
        y=df['W/W Growth'].values,
        name='W/W Growth',
        xaxis='x1',
        yaxis='y3',
        marker=dict(
            color='rgb(0,153,153)')
    )

    # NR ratio
    NR_ratio = go.Scatter(
        x=df.index,
        y=df['N/R Ratio'].values,
        name='N/R Ratio',
        xaxis='x1',
        yaxis='y4',
        marker=dict(
            color='rgb(192,192,192)')
    )

    # axis object
    axis = dict(
        showline=True,
        zeroline=False,
        showgrid=True,
        ticklen=4,
        gridcolor='#ffffff',
        tickfont=dict(size=10),
        linecolor='black',
        linewidth=1
    )

    layout = dict(
        width=950,
        height=800,
        autosize=True,
        barmode='group',
        margin={"l": 100, "r": 0, "t": 10, "b": 0, "pad": 0},
        showlegend=True,
        xaxis1=dict(axis, **dict(domain=[0, 1], anchor='y1', showticklabels=True,
                                 ticktext=df.index,
                                 tickvals=df.index,
                                 tickangle=-45),
                    rangeselector=dict(
                        buttons=list([
                            dict(count=1,
                                 label="1m",
                                 step="month",
                                 stepmode="backward"),
                            dict(count=3,
                                 label="3m",
                                 step="month",
                                 stepmode="backward"),
                            dict(count=6,
                                 label="6m",
                                 step="month",
                                 stepmode="backward"),
                            dict(count=1,
                                 label="1yr",
                                 step="year",
                                 stepmode="backward"),
                            dict(step="all")
                        ])
                    ),
                    rangeslider=dict(
                        visible=False,
                        thickness=0.05
                    ),
                    type="date"),
        yaxis1=dict(axis, **dict(domain=[0, 0.10], anchor='x1', title='New users<br>per source')),
        yaxis2=dict(axis, **dict(domain=[0.12, 0.7], anchor='x1', title='New/Active/<br>Returning')),
        yaxis3=dict(axis, **dict(domain=[0.705, 0.85], anchor='x1', hoverformat='.2f', title='Growth%')),
        yaxis4=dict(axis, **dict(domain=[0.855, 1], anchor='x1', title='NR<br>Ratio')),
        plot_bgcolor='rgba(228, 222, 239, 0.65)',
        hovermode='closest'
    )

    data = [new1, organic, non_organic,
            new2, active, returning,
            growth,
            NR_ratio]

    return dict(data=data, layout=layout)
