# -*- coding: utf-8 -*-
import logging
from itertools import product
from ads import (
    build_extra_ads,
    fix_base_ad,
    format_ads,
    format_sitelinks,
    get_geo_sitelinks,
    get_group_name,
    get_location,
    get_phrase,
    get_title_by_phrase,
    get_url
)
from utils import get_geo_kwargs

logger = logging.getLogger(__name__)


class Campaign(object):
    def __init__(self, options=None, geo_dict=None, **kwargs):
        super(Campaign, self).__init__()

        self.options = options
        self.geo_dict = geo_dict

        if not options.get('group_by'):
            group_name = get_group_name(options['group_title_template'], self.geo_dict['geobase'], options['group_lang'])
        else:
            group_name = None

        sitelinks = get_geo_sitelinks(geo_dict['Geo'], options['sitelinks'])
        if options.get('group_by') is None:
            sitelinks = format_sitelinks(sitelinks, self.geo_dict['kwargs'])
            options['ads'] = format_ads(options['ads'], self.geo_dict['kwargs'])
            options['ads'][0] = fix_base_ad(options['ads'][0], options['ads'][1:])
        self.sitelinks = sitelinks
        self.base_ad, self.extra_ads = options['ads'][0], options['ads'][1:]

        self.template = {
            'IsExtra': None,
            'GroupName': group_name,
            'GroupID': None,
            'CampType': u'Текстово-графическая кампания',
            'CampName': self._get_camp_name(),
            'Phrase': None,
            'Title1': None,
            'Title2': None,
            'Text': None,
            'Url': geo_dict.get('Url') if geo_dict.get('Url') else options.get('Url'),
            'DisplayLink': self._get_display_link() if options.get('group_by') in [None, 'destination'] else None,
            'Bid': options['bid'],
            'SitelinkTitles': self.sitelinks['Titles'],
            'Sitelinks': self.sitelinks['Sitelinks'],
            'SitelinkTexts': self.sitelinks['Texts'],
            'ImageUrl': geo_dict['ImageUrl'] if options.get('group_by') in [None, 'destination'] else None,
            'Callouts': options['сallouts'],
            'NegativeKeywords': options['negative_keywords']
        }
        self.groups = options['groups']

        self.ads = []

    def build(self):
        for group_id, group_template in enumerate(self.groups.itervalues(), 1):
            self.ads += self._build_group(group_template, group_id)

    def _build_group(self, group_template, group_id):
        ad_template = self.template.copy()
        ad_template['GroupID'] = group_id

        if group_template.get('GroupName'):
            ad_template['GroupName'] = get_group_name(group_template['GroupName'], self.geo_dict['geobase'],
                                                      self.options['group_lang'])
        for key in ['Url', 'Sitelinks']:
            ad_template[key] = get_url(ad_template[key],
                                       campaign_name=self.template['CampName'], group_name=self.template['GroupName'],
                                       code=self.geo_dict['Code'])

        group = []
        for phrase in group_template['Phrases']:
            ad = ad_template.copy()
            ad['IsExtra'] = u'-'

            ad['Phrase'] = get_phrase(phrase, get_location(self.geo_dict['geobase'], None, 'ru'))
            if len(group_template['Phrases']) == 1:
                ad['Title1'] = get_title_by_phrase(ad['Phrase'], self.base_ad['Title1'])
            else:
                ad['Title1'] = self.base_ad['Title1']

            ad['Title2'] = self.base_ad['Title2']
            ad['Text'] = self.base_ad['Text']

            group.append(ad)

        group += build_extra_ads(self.extra_ads, ad_template)

        return group

    def _get_camp_name(self):
        key = 'Runame' if self.options['camp_lang'] == 'ru' else 'Enname'
        return self.options['camp_title_template'].format(geo=self.geo_dict['geobase'][key])

    def _get_display_link(self, geobase=None):
        if not geobase:
            geobase = self.geo_dict['geobase']

        group_name = self.options['group_title_template'].lower()
        return group_name.format(geo=geobase['Runame']).replace(' ', '-')


class DirCampaign(Campaign):
    def __init__(self, options=None, geo_dict=None, codes=None):
        super(DirCampaign, self).__init__(options, geo_dict)
        self.codes = codes

    def build(self):
        for group_id, (geo_dict, group_template) in enumerate(product(
                self.geo_dict['Directions'], self.groups.itervalues()), 1):

            if self.options['group_by'] == 'origin':
                self.ads += self._build_dir_group(group_template, group_id, self.geo_dict, geo_dict)

            elif self.options['group_by'] == 'destination':
                self.ads += self._build_dir_group(group_template, group_id, geo_dict, self.geo_dict)

    def _build_dir_group(self, group_template, group_id, origin=None, destination=None):
        group_name = get_group_name(
            group_template.get('GroupName', self.options['group_title_template']),
            origin['geobase'] if True else '',
            self.options['group_lang']
        )

        geo_kwargs = origin['kwargs'].copy()
        geo_kwargs.update(destination['kwargs'].copy())
        sitelinks = format_sitelinks(self.sitelinks.copy(), geo_kwargs,
                                     utm={'campaign_name': self.template['CampName'], 'group_name': group_name})

        template = self.template.copy()
        template.update({
            'GroupName': group_name,
            'GroupID': group_id,
            'Url': get_url(
                template['Url'],
                code1=self.codes.get(origin['Geo']), code2=self.codes.get(destination['Geo']),
                campaign_name=template['CampName'], group_name=group_name),
            'DisplayLink':
                template['DisplayLink'] if template['DisplayLink'] else self._get_display_link(destination['geobase']),
            'SitelinkTitles': sitelinks['Titles'],
            'Sitelinks': sitelinks['Sitelinks'],
            'SitelinkTexts': sitelinks['Texts'],
            'ImageUrl': template['ImageUrl'] if template['ImageUrl'] else destination['ImageUrl']
        })

        base_ad = format_ads([self.base_ad.copy(), ], geo_kwargs).pop()
        extra_ads = format_ads(self.extra_ads, geo_kwargs)
        base_ad = fix_base_ad(base_ad, extra_ads)

        group = []
        for phrase in group_template['Phrases']:
            ad = template.copy()
            ad['IsExtra'] = u'-'
            ad['Title2'] = base_ad['Title2']
            ad['Text'] = base_ad['Text']

            ad['Phrase'] = get_phrase(
                phrase, u'[из {}] [в {}]'.format(
                    origin['geobase']['RunameGenitive'], destination['geobase']['RunameAccusative'])
            )
            ad['Title1'] = base_ad['Title1']
            group.append(ad)

            ad = ad.copy()
            ad['Phrase'] = get_phrase(
                phrase, u'[{} {}]'.format(origin['geobase']['Runame'], destination['geobase']['Runame'])
            )
            ad['Title1'] = base_ad['Title1']
            group.append(ad)

        group += build_extra_ads(extra_ads, template)

        return group


class StaticCampaign(object):
    def __init__(self, camp_name=None, options=None, geo_list=None, codes=None):
        self.camp_name = camp_name

        self.options = options
        self.sitelinks = get_geo_sitelinks(None, options['sitelinks'])
        self.base_ad, self.extra_ads = options['ads'][0], options['ads'][1:]

        self.geo_list = geo_list
        self.codes = codes

        self.ads = []

    def build(self):
        for group_id, (geo_dict, group_template) in enumerate(product(
                self.geo_list, self.options['groups'].itervalues()), 1):
            self.ads += self._build_group(group_id, geo_dict, group_template)

    def _build_group(self, group_id, geo_dict, group_template):
        geo_kwargs = get_geo_kwargs(is_dest=True if not geo_dict['kwargs'].get('geo2') else False)
        geo_kwargs.update(geo_dict['kwargs'])

        sitelinks = format_sitelinks(self.sitelinks.copy(), geo_kwargs)
        template = self._get_template(group_id, geo_dict, group_template, sitelinks)

        base_ad = format_ads([self.base_ad.copy(), ], geo_kwargs).pop()
        extra_ads = format_ads(self.extra_ads, geo_kwargs)
        base_ad = fix_base_ad(base_ad, extra_ads)

        group = []
        for phrase in group_template['Phrases']:
            ad = template.copy()
            ad['IsExtra'] = u'-'

            ad['Phrase'] = self._get_phrase(phrase, geo_dict['geobase'])

            if len(group_template['Phrases']) == 1:
                ad['Title1'] = get_title_by_phrase(ad['Phrase'], base_ad['Title1'])
            else:
                ad['Title1'] = base_ad['Title1']
            ad['Title2'] = base_ad['Title2']
            ad['Text'] = base_ad['Text']

            group.append(ad)

        group += build_extra_ads(extra_ads, template)
        return group

    def _get_phrase(self, phrase, geobase):
        if self.camp_name == 'Origins':
            location = get_location(geobase, None, 'ru', group_by=self.options['group_by'])

        elif self.camp_name == 'Destinations':
            location = get_location(None, geobase, 'ru', group_by=self.options['group_by'])

        else:
            location = u'{}'.format(geobase['Runame'], u'-!из -!в')

        if self.camp_name in ['Origins', 'Destinations']:
            location = u'[{}]'.format(location)

        return get_phrase(phrase, location)

    def _get_template(self, group_id, geo_dict, group_template, sitelinks):
        group_name = get_group_name(
            group_template.get('GroupName', self.options['group_title_template']),
            geo_dict['geobase'],
            self.options['group_lang']
        )
        utm = {'campaign_name': self.camp_name, 'group_name': group_name}

        template = {
            'IsExtra': None,
            'GroupName': group_name,
            'GroupID': group_id,
            'CampType': u'Текстово-графическая кампания',
            'CampName': self.camp_name,
            'Phrase': None,
            'Title1': None,
            'Title2': None,
            'Text': None,
            'Url': self._get_url(geo_dict, utm),
            'DisplayLink': self._get_display_link(geo_dict['geobase']),
            'Bid': self.options['bid'],
            'SitelinkTitles': sitelinks['Titles'],
            'Sitelinks': get_url(sitelinks['Sitelinks'], **utm),
            'SitelinkTexts': sitelinks['Texts'],
            'ImageUrl': geo_dict['ImageUrl'],
            'Callouts': self.options['сallouts'],
            'NegativeKeywords': self.options['negative_keywords']
        }
        return template

    def _get_location(self, geobase, lang):
        if self.camp_name == 'Origins':
            return get_location(geobase, None, lang, group_by=self.options['group_by'])

        elif self.camp_name == 'Destinations':
            return get_location(None, geobase, lang, group_by=self.options['group_by'])

        elif self.camp_name == 'Locations':
            if lang == 'ru':
                return geobase['Runame']
            elif lang == 'en':
                return geobase['Enname']

    def _get_url(self, geo_dict, utm):
        for k in ['code1', 'code2']:
            utm[k] = self.codes.get(geo_dict['Geo'])

        if self.camp_name == 'Origins':
            return get_url(self.options['OriginUrl'], **utm)

        elif self.camp_name == 'Destinations':
            return get_url(self.options['DestUrl'], **utm)

        elif self.camp_name == 'Locations':
            return get_url(geo_dict['Url'], **utm)

    def _get_display_link(self, geobase):
        group_name = self.options['group_title_template'].lower()
        return group_name.format(geo=geobase['Runame']).replace(' ', '-')
