# -*- coding: utf-8 -*-
import werkzeug
from itertools import groupby

from odoo import fields, http, _
from odoo.http import request
from odoo.addons.prime_snippets.models.filter import Filter, FilterItem
from query_strings import range_query, min_max_range_query
import json


class Result:

    def __init__(self, row, enterprise_number, num_rooms, num_beds, group, island_code):
        self.row = list(row)
        self.enterprise_number = enterprise_number
        self.group = group
        self.num_rooms = num_rooms
        self.num_beds = num_beds
        self.island_code = island_code


class enterprise_type_list(http.Controller):

    @http.route(['/tms/<string:island_code>'], type='http', auth="public", website=True)
    def index(self, island_code, **kw):
        # print "Begin to search"

        results, ids_types = [], []
        Enterprise = request.env['etourism.enterprise']
        EnterpriseType = request.env['ecom.ebusiness.type']
        Island = request.env['ecom.location']
        IslandImages = request.env['ecom.location.image']
        domain = [('ebusiness_type_code', '=', 'ALO'), ('island_code', '=', island_code), ('is_legal', '=', True),
                  ('directory_state', '=', 'published')]
        values, enterprises_booking, island_banners = {}, {}, {}

        ents_group = Enterprise.read_group(domain, ["id", "enterprise_type_id"], groupby=["enterprise_type_id"],
                                           orderby="enterprise_type_id")
        for res in ents_group:
            if res['enterprise_type_id']:
                ids_types.append(res['enterprise_type_id'][0])

        step = 20

        types = EnterpriseType.search([('id', 'in', ids_types)], limit=step, offset=0, order='name')
        enterprises_booking = Enterprise.search(
            [('ebusiness_type_code', '=', 'ALO'), ('island_code', '=', island_code), ('ebusiness_state', '=', 'online'),
             ('is_legal', '=', True)], limit=4, offset=0, order='rating desc,name')
        current_island = Island.search([('code', '=', island_code)], limit=1)
        if current_island:
            island_banners = IslandImages.search(
                [('location_id', '=', current_island.id), ('directory_image', '=', True)], limit=5)

        values = {
            'types': types,
            'island_code': island_code,
            'island_id': current_island,
            'enterprises_booking': enterprises_booking,
            'island_banners': island_banners,
            'default_island': 1,
            'default_feature': 0
        }
        # print "VALUES:::::::::::::::::::::::::::::::::::::::::::::::::", values
        return request.render("web_etourism_directory.index", values)

    # Enterprise List by Category
    @http.route(['/tms/<string:island_code>/<string:ent_type_code>/page/<int:page>',
                 '/tms/<string:island_code>/<string:ent_type_code>'], type='http', auth="public", website=True)
    def enterprise_list(self, island_code, ent_type_code, page=1, **searches):
        #print "List Enterprise"
        cities_ids, amenities_ids, entities_ids = [], [], []
        cr = request.cr
        for key, value in searches.iteritems():
            if 'city' in key:
                cities_ids.append(int(value))
            if 'amenity' in key:
                amenities_ids.append(int(value))
        Enterprise = request.env['etourism.enterprise']
        Amenity = request.env['etourism.amenities']
        searches.setdefault('classification', 'all')
        searches.setdefault('adherent', '')
        searches.setdefault('range', "0;'NaN'")
        #print "searches.get('range'): ", searches.get('range')
        domain_search = {}
        adherent = 'off'
        classifications = [
            ['all', _('All'), [("number_stars", ">=", 0)], 0],
            ['5', _('5 stars'), [("number_stars", "=", 5)], 0],
            ['4', _('4 stars'), [("number_stars", "=", 4)], 0],
            ['3', _('3 stars'), [("number_stars", "=", 3)], 0],
            ['2', _('2 stars'), [("number_stars", "=", 2)], 0],
            ['1', _('1 stars'), [("number_stars", "=", 1)], 0],
        ]

        current_classification = None
        for classification in classifications:
            if searches["classification"] == classification[0]:
                domain_search["classification"] = classification[2]
                if classification[0] != 'all':
                    current_classification = classification[1]

        island = request.env['ecom.location'].sudo().search(
            [('code', '=', island_code)], limit=1)

        enterprise_type = request.env['ecom.ebusiness.type'].sudo().search(
            [('code', '=', ent_type_code)], limit=1)

        #print "Adherent:::::::::::::::::"
        #print searches["adherent"]
        if searches["adherent"]:
            adherent = searches['adherent']
            domain_search["ebusiness_state"] = [("ebusiness_state", "=", 'online')]

        if cities_ids:
            domain_search["city"] = [("local_id", "in", cities_ids)]

        if amenities_ids:
            myList = ','.join(map(str, amenities_ids))
            cr.execute("""select v2.* from (SELECT v.enterprise_id,v.name_enterprise, array_agg(a.id) as aggreg
FROM view_amenity_enterprise v
LEFT OUTER JOIN etourism_amenities a
ON v.amenity_id = a.id
WHERE v.ebusiness_type_code='ALO' and v.island_code='%s' and v.enterprise_type_id=%s
GROUP BY v.enterprise_id,v.name_enterprise) v2
where array[%s] <@ v2.aggreg""" % (island_code, enterprise_type.id, myList))
            entities = cr.fetchall()
            if entities:
                for entity in entities:
                    entities_ids.append(entity[0])
            domain_search["entities"] = [("id", "in", entities_ids)]

        def dom_without(without):
            domain = [('ebusiness_type_code', '=', 'ALO'), ('island_code', '=', island_code), ('is_legal', '=', True),
                      ('enterprise_type_id', '=', enterprise_type.id), ('directory_state', '=', 'published')]
            for key, search in domain_search.items():
                if key != without:
                    domain += search
            return domain

        prices = {}
        enterprises_domain = ('id', '!=', None)
        if searches.get('adherent') == 'on':
            range = searches.get('range').split(';')
            cr.execute(min_max_range_query.format(range_query=range_query.format(min=0, max="'NaN'")))
            price_range = cr.fetchall()
            #print "PRICE RANGE: ", price_range
            min = f = int(price_range[0][0])
            max = t = int(price_range[0][1])
            if range[1] != "'NaN'":
                f = int(range[0])
                t = int(range[1])
                cr.execute(range_query.format(min=f, max=t))
                price_enterprise = cr.fetchall()
                print "price_enterprise: ", price_enterprise
                enterprises_id = [enterprise_price[0] for enterprise_price in price_enterprise]
                enterprises_domain = ('id', 'in', enterprises_id)

            prices = {'min': min, 'max': max, 'from': f, 'to': t}
        #print "domain: ", dom_without("none")
        #print "PRICES: ", prices

        domain = dom_without("none")
        domain.append(enterprises_domain)
        cities = Enterprise.read_group([('directory_state', '=', 'published'), ('ebusiness_type_code', '=', 'ALO'),
                                        ('island_code', '=', island_code),
                                        ('enterprise_type_id', '=', enterprise_type.id), enterprises_domain],
                                       ["id", "local_id"], groupby="local_id", orderby="local_id")
        amenities = Amenity.search([('amenity_type', '=', 'enterprise')], order='name')

        step = 10  # Number of enterprises per page
        #print "SEARCH COUNT: ", dom_without("none")
        enterprise_count = Enterprise.search_count(domain)
        #print "enterprise_count",enterprise_count
        pager = request.website.pager(
            url='/tms/' + island_code + '/' + ent_type_code,
            url_args={
                'classification': searches.get('classification'),
                'default_island': 1,
                'default_feature': 0,
                'adherent': searches.get('adherent'),
                'range': searches.get('range')

            },
            total=enterprise_count,
            page=page,
            step=step,
            scope=5)

        order = 'name'
        #print "DOMAINS ENT: ", domain
        enterprises = Enterprise.search(domain, limit=step, offset=pager['offset'], order=order)

        # enterprises = request.env['etourism.enterprise'].sudo().search([('ebusiness_type_code', '=', 'ALO'), ('island_code', '=', island_code),('enterprise_type_id','=',enterprise_type.id)])

        filters = self.build_filters(searches, classifications, cities, cities_ids, amenities, amenities_ids, adherent,
                                     [], [], prices)
        #print "ENTERPRISE: ", enterprises
        values = {
            'enterprises': enterprises,
            'island_id': island,
            'island_code': island_code,
            'island_name': island.name,
            'ent_type_code': ent_type_code,
            'enterprise_type': enterprise_type.name,
            'enterprises_number': len(enterprises),
            'classifications': classifications,
            'cities': cities,
            'amenities': amenities,
            'pager': pager,
            'searches': searches,
            'search_path': "?%s" % werkzeug.url_encode(searches),
            'filtros': filters,
            'default_island': 1,
            'default_feature': 0,
            'enterprise_count':enterprise_count
        }
        return request.render("web_etourism_directory.enterpriseList", values)

    # Enterprises List
    @http.route(['/tms/<string:island_code>/enterprises', '/tms/<string:island_code>/enterprises/page/<int:page>'],
                type='http',
                auth="public", website=True)
    def enterprises(self, island_code, page=1, **searches):
        #print "SEARCH::::::", searches
        #print "ISLAND_CODE:::::::", island_code
        cities_ids, amenities_ids, entities_ids, enterprise_types = [], [], [], []
        cr = request.cr
        for key, value in searches.iteritems():
            if 'city' in key:
                cities_ids.append(int(value))
            if 'amenity' in key:
                amenities_ids.append(int(value))
        Enterprise = request.env['etourism.enterprise']
        EnterpriseType = request.env['ecom.ebusiness.type']
        Amenity = request.env['etourism.amenities']
        searches.setdefault('classification', 'all')
        searches.setdefault('adherent', '')
        domain_search = {}
        adherent = 'on'
        classifications = [
            ['all', _('All'), [("number_stars", ">=", 0)], 0],
            ['5', _('5 stars'), [("number_stars", "=", 5)], 0],
            ['4', _('4 stars'), [("number_stars", "=", 4)], 0],
            ['3', _('3 stars'), [("number_stars", "=", 3)], 0],
            ['2', _('2 stars'), [("number_stars", "=", 2)], 0],
            ['1', _('1 stars'), [("number_stars", "=", 1)], 0],
        ]
        for classification in classifications:
            if searches["classification"] == classification[0]:
                domain_search["classification"] = classification[2]

        island = request.env['ecom.location'].sudo().search(
            [('code', '=', island_code)], limit=1)

        if searches["adherent"]:
            adherent = searches['adherent']
            domain_search["ebusiness_state"] = [("ebusiness_state", "=", 'online')]

        if cities_ids:
            domain_search["city"] = [("local_id", "in", cities_ids)]

        if amenities_ids:
            myList = ','.join(map(str, amenities_ids))
            cr.execute("""select v2.* from (SELECT v.enterprise_id,v.name_enterprise, array_agg(a.id) as aggreg
        FROM view_amenity_enterprise v
        LEFT OUTER JOIN etourism_amenities a
        ON v.amenity_id = a.id
        WHERE v.ebusiness_type_code='ALO' and v.island_code='%s'
        GROUP BY v.enterprise_id,v.name_enterprise) v2
        where array[%s] <@ v2.aggreg""" % (island_code, myList))
            entities = cr.fetchall()
            if entities:
                for entity in entities:
                    entities_ids.append(entity[0])
            domain_search["entities"] = [("id", "in", entities_ids)]

        amenities = Amenity.search([('amenity_type', '=', 'enterprise')], order='name')

        if searches["adherent"]:
            adherent = searches['adherent']
            domain_search["ebusiness_state"] = [("ebusiness_state", "=", 'online')]

        if searches['search']:
            def dom_without(without):
                domain = [('ebusiness_type_code', '=', 'ALO'), ('island_code', '=', island_code),
                          ('is_legal', '=', True),
                          ('name', 'ilike', searches["search"]), ('directory_state', '=', 'published')]
                for key, search in domain_search.items():
                    if key != without:
                        domain += search
                return domain

            search_result = Enterprise.sudo().search(dom_without("none"))
            for key, value in searches.iteritems():
                if 'city' in key:
                    cities_ids.append(int(value))
            cities = Enterprise.read_group(dom_without("none"), ["id", "local_id"],
                                           groupby="local_id", orderby="local_id")
            enterprise_types = Enterprise.read_group(dom_without("none"), ["enterprise_type_id"],
                                                     groupby="enterprise_type_id", orderby="enterprise_type_id")

            enterprise_type_ids = domain_search["enterprise_type_id"] = [("enterprise_type_id", "in", enterprise_types)]

            step = 10  # Number of enterprises per page
            enterprise_count = len(search_result)
            pager = request.website.pager(
                url='/tms/' + island_code + '/' + 'enterprises',
                url_args={
                    'classification': searches.get('classification'),
                    'enterprise_type_id': searches.get('enterprise_type_id'),
                    'city': searches.get('city'),
                    'adherent': searches.get('adherent'),
                    'amenity': searches.get('amenity'),
                    'search': searches.get('search'),
                    'default_island': 1,

                },
                total=enterprise_count,
                page=page,
                step=step,
                scope=5)
            aux = search_result[pager['offset']:]
            lim = step
            if len(aux) < step:
                lim = len(aux)
            #print "LIM::::::", lim
            count = 0
            enterprises = []
            for a in aux:
                if count < lim:
                    #print a['enterprise_type_id'].code
                    enterprises.append(a)
                    count += 1

            filters = self.build_filters(searches, classifications, cities, cities_ids, amenities, amenities_ids,
                                         adherent, enterprise_type_ids, enterprise_types)
            values = {
                'island_code': island_code,
                'island_id': island,
                'island_name': island.name,
                'enterprises': enterprises,
                'enterprises_number': len(enterprises),
                'filtros': filters,
                'pager': pager,
                'default_island': 1,
                'enterprise_count':enterprise_count
            }
            return request.render("web_etourism_directory.enterprises", values)

    # Enterprise Details
    @http.route(['/tms/<string:island_code>/<string:ent_type_code>/<model("etourism.enterprise"):enterprise>'],
                type='http', auth="public", website=True)
    def enterprise_details(self, island_code, ent_type_code, enterprise, **post):

        island = request.env['ecom.location'].sudo().search(
            [('code', '=', island_code)], limit=1)

        enterprise_type = request.env['ecom.ebusiness.type'].sudo().search(
            [('code', '=', ent_type_code)], limit=1)

        image = request.env['etourism.enterprise.image'].sudo().search(
            [('enterprise_id', '=', enterprise.id), ('main_image', '=', True)], limit=1)

        values = {
            'enterprise': enterprise,
            'main_object': enterprise,
            'island_code': island_code,
            'island_id': island,
            'island_name': island.name,
            'enterprise_type': enterprise_type.name,
            'ent_type_code': ent_type_code,
            'main_image': image,
            'default_island': 1
        }

        return request.render('web_etourism_directory.enterprise_details', values)

    def build_filters(self, searches, classifications, cities, cities_ids, amenities, amenities_ids, adherent,
                      enterprise_types_ids=[], enterprise_types=[], prices={}):
        filters = []
        # prices = {'max': 10, 'from': 2, 'to': 7, 'min': 0}
        # prices = {'max': 4200, 'from': 2404, 'to': 4200, 'min': 2500}
        #print "PRICES FILTT: ", prices
        filter_items = []
        filter_items.append(
            FilterItem('adherent', 1,
                       'checked' if adherent == 'on' else 'unchecked', -1)
        )

        filters.append(Filter(_('Online Booking'), 'bool', filter_items, 'adherent'))

        # PRICE RANGE FILTER
        if prices:
            #print "PRICES RANGEs"
            filter_items = []
            filter_items.append(
                FilterItem('price', 1,
                           'checked', -1, 0, prices)
            )

            filters.append(Filter(_('Price Range'), 'range', filter_items, 'price'))

        if enterprise_types:
            filter_items = []

            for ent_type_filter in [ent_type['enterprise_type_id'] for ent_type in enterprise_types]:
                if ent_type_filter:
                    #print ent_type_filter
                    filter_items.append(
                        FilterItem(ent_type_filter[1], ent_type_filter[0],
                                   'checked' if ent_type_filter[0] in enterprise_types_ids else 'unchecked', -1)
                    )
            filters.append(Filter(_('Enterprise Types'), 'radio', filter_items, 'enterprise_type_id'))

        filter_items = []
        for classification_filter in [list((classification[0], classification[1], classification[3])) for classification
                                      in classifications]:
            if classification_filter:
                filter_items.append(
                    FilterItem(classification_filter[1], classification_filter[0],
                               'checked' if searches['classification'] == str(
                                   classification_filter[0]) else 'unchecked',
                               -2, 1)
                )

        filters.append(Filter(_('Classification'), 'radio', filter_items, 'classification'))

        filter_items = []
        for city_filter in [city['local_id'] for city in cities]:
            if city_filter:
                filter_items.append(
                    FilterItem(city_filter[1], city_filter[0],
                               'checked' if city_filter[0] in cities_ids else 'unchecked', -1)
                )

        filters.append(Filter(_('Cities/Locations'), 'checkbox', filter_items, 'city'))

        filter_items = []
        for amenity_filter in amenities:
            if amenity_filter:
                filter_items.append(
                    FilterItem(amenity_filter.name, amenity_filter.id,
                               'checked' if amenity_filter.id in amenities_ids else 'unchecked', -1)
                )

        filters.append(Filter(_('Amenities'), 'checkbox', filter_items, 'amenity'))

        return filters
