# -*- coding: utf-8 -*-
from datetime import datetime, timedelta
import csv
from jinja2 import Template
import logging
from os import remove
from os.path import dirname, join
import pandas as pd
import pyper as pr
import statface_client
from textwrap import dedent
from yt import wrapper as yt

from data_worker import CONFIG, SECRET
from data_worker.yql_worker import YQLWorker
from utils import read_table, get_query_text, read_query_from_arc, write_table

logger = logging.getLogger(__name__)


def replace_nulls_for_forecast(df):
    df = df.replace(0, pd.np.nan)
    df.tail(100).fillna(method='ffill', inplace=True)
    df = df.fillna(0)
    return df


def auto_daily_cost_forecast(fact_df):
    from_date = (datetime.strptime(fact_df.date.max(), '%Y-%m-%d') + timedelta(days=1)).strftime('%Y-%m-%d')
    logger.info('make auto forecast from %s', from_date)

    series_path = join(dirname(dirname(__file__)), 'series.csv')
    fact_df = replace_nulls_for_forecast(fact_df)
    fact_df.to_csv(series_path, sep=';', index=False, encoding='utf-8', quoting=csv.QUOTE_NONE, decimal='.')
    fact_df['type'] = 'fact'

    forecast_path = join(dirname(dirname(__file__)), 'auto_%s.csv' % from_date)
    with open(join(dirname(__file__), 'model.R')) as fd:
        rscript_template = Template(dedent(fd.read().decode('utf8')).strip())
        rscript_text = rscript_template.render(wd=dirname(dirname(__file__)), series_path=series_path,
                                               forecast_path=forecast_path)
    r = pr.R()
    r.run(rscript_text)

    forecast_df = pd.read_csv(forecast_path, sep=';')
    forecast_df['date'] = [day.strftime('%Y-%m-%d') for day in pd.date_range(from_date, periods=90).tolist()]
    forecast_df['type'] = 'forecast'

    df = pd.concat([fact_df, forecast_df])
    yt_forecast_path = '//home/vipplanners/weekly_update/auto_forecasts/%s' % from_date
    write_table(yt_forecast_path, CONFIG['forecast']['schema'], df)

    remove(series_path)
    remove(forecast_path)

    monthly_forecast(yt_forecast_path)


def daily_cost_forecast(from_date):
    logger.info('load manual forecast from %s', from_date)

    fact_df = read_table(CONFIG['series']['target_path'], [col['name'] for col in CONFIG['series']['schema']])
    fact_df = fact_df[fact_df['date'] < from_date]
    fact_df = replace_nulls_for_forecast(fact_df)
    fact_df['type'] = 'fact'

    forecast_path = join(dirname(dirname(__file__)), '%s.csv' % from_date)
    forecast_df = pd.read_csv(forecast_path, sep=';')
    forecast_df['date'] = [day.strftime('%Y-%m-%d') for day in pd.date_range(from_date, periods=90).tolist()]
    forecast_df['type'] = 'forecast'
    fact_df['type'] = 'fact'

    df = pd.concat([fact_df, forecast_df])
    yt_forecast_path = '//home/vipplanners/weekly_update/forecasts/%s' % from_date
    write_table(yt_forecast_path, CONFIG['forecast']['schema'], df)

    monthly_forecast(yt_forecast_path)


def monthly_forecast(daily_forecast_path):
    yt_client = yt.YtClient(token=SECRET['token'], proxy='hahn')
    from_dt = yt_client.get_attribute(daily_forecast_path, 'key')
    logger.info('make monthly forecast from %s', from_dt)

    monthly_forecast_path = daily_forecast_path.replace('auto_forecasts', 'auto_monthly_forecasts') \
        if 'auto_forecasts' in daily_forecast_path else daily_forecast_path.replace('forecasts', 'monthly_forecasts')

    query = get_query_text('net').format(forecast_path=daily_forecast_path, monthly_forecast_path=monthly_forecast_path)
    yql_worker = YQLWorker(query_name='YQL: net', query=query)
    yql_worker.run()

    ya_forecasts()

    dash_query = read_query_from_arc()
    yql_worker = YQLWorker(query_name='YQL: dash', query=dash_query)
    yql_worker.run()


def get_last_series():
    df = read_table('//home/vipplanners/weekly_update/forecasts/%s' % get_last_forecast_date(),
                    [col['name'] for col in CONFIG['forecast']['schema']])
    df = df[df['type'] == 'fact'].fillna(0.0)
    return df


def get_last_forecast_date():
    yt_client = yt.YtClient(token=SECRET['token'], proxy='hahn')
    forecasts = yt_client.list('//home/vipplanners/weekly_update/forecasts')
    last_date = max([date for date in forecasts])
    return last_date


def ya_forecasts():
    logger.info('get statface forecasts')

    cli = statface_client.StatfaceClient(oauth_token=SECRET['token'], host=statface_client.STATFACE_PRODUCTION)
    df = pd.DataFrame()
    for k, config in CONFIG['statface'].iteritems():
        report = cli.get_report(config['statface_path'])
        data = report.download_data(**config['statface_params'])

        report_df = pd.DataFrame(data)[['fielddate', 'value']].rename(columns={'fielddate': 'date', 'value': k})
        report_df['date'] = report_df['date'].apply(lambda cell: cell[:10])
        report_df = report_df.set_index('date')
        if df.empty:
            df = report_df.copy()
        else:
            df = df.join(report_df, how='outer')

    df['search'] = df['search_rf'] + df['search_not_rf']
    df['internal_inc_ps'] = df['internal_search'] + df['internal_networks']
    df = df.rename(columns={
        'partner_networks': 'external_wo_ps',
        'partner_search': 'external_ps',
    }).reset_index().loc[:, ['date', 'search', 'internal_inc_ps', 'external_wo_ps', 'external_ps']]

    write_table('//home/vipplanners/weekly_update/ya_forecasts/%s' % datetime.today().strftime('%Y-%m-%d'),
                CONFIG['statface_result']['schema'], df)
