# w.c.s. - web application for online forms
# Copyright (C) 2005-2020  Entr'ouvert
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.

from django.utils.six.moves.urllib import parse as urlparse
from quixote import get_publisher

from wcs.carddef import CardDef
from wcs.formdef import FormDef
from wcs.qommon.storage import StorableObject, Equal
from wcs.qommon.misc import simplify


class CustomView(StorableObject):
    _names = 'custom-views'

    title = None
    slug = None
    user_id = None
    visibility = 'owner'
    formdef_type = None
    formdef_id = None
    columns = None
    filters = None
    order_by = None

    @property
    def user(self):
        return get_publisher().user_class.get(self.user_id)

    @user.setter
    def user(self, value):
        self.user_id = str(value.id)

    @property
    def formdef(self):
        if self.formdef_type == 'formdef':
            return FormDef.get(self.formdef_id)
        else:
            return CardDef.get(self.formdef_id)

    @formdef.setter
    def formdef(self, value):
        self.formdef_id = str(value.id)
        self.formdef_type = value.xml_root_node

    def match(self, user, formdef):
        if self.visibility == 'owner' and self.user_id != str(user.id):
            return False
        if self.formdef_type != formdef.xml_root_node:
            return False
        if self.formdef_id != str(formdef.id):
            return False
        return True

    def set_from_qs(self, qs):
        parsed_qs = urlparse.parse_qsl(qs)
        self.columns = {
            'list': [
                {'id': key} for (key, value) in parsed_qs if value == 'on' and not key.startswith('filter-')
            ],
        }

        columns_order = [x[1] for x in parsed_qs if x[0] == 'columns-order']
        if columns_order:
            field_order = columns_order[0].split(',')

            def field_position(x):
                if x['id'] in field_order:
                    return field_order.index(x['id'])
                return 9999

            self.columns['list'].sort(key=field_position)

        order_by = [x[1] for x in parsed_qs if x[0] == 'order_by']
        if order_by:
            self.order_by = order_by[0]

        self.filters = {key: value for (key, value) in parsed_qs if key.startswith('filter')}

    def ensure_slug(self):
        if self.slug:
            return
        clauses = [
            Equal('formdef_type', self.formdef_type),
            Equal('formdef_id', self.formdef_id),
            Equal('visibility', self.visibility),
        ]
        if self.visibility == 'owner':
            clauses.append(Equal('user_id', self.user_id))
        existing_slugs = set([x.slug for x in self.select(clauses)])
        base_slug = simplify(self.title)
        if base_slug.startswith('user-'):
            # prevent a slug starting with user- as it's used in URLs
            base_slug = 'userx-' + base_slug[5:]
        self.slug = base_slug
        i = 2
        while self.slug in existing_slugs:
            self.slug = '%s-%s' % (base_slug, i)
            i += 1

    def get_url_slug(self):
        if self.visibility == 'owner':
            return 'user-%s' % self.slug
        return self.slug

    def store(self, *args, **kwargs):
        self.ensure_slug()
        return super(CustomView, self).store(*args, **kwargs)

    def get_columns(self):
        if self.columns and 'list' in self.columns:
            return [x['id'] for x in self.columns['list']]
        else:
            return []

    def get_filter(self):
        return self.filters.get('filter')

    def get_filters_dict(self):
        return self.filters

    def get_default_filters(self):
        return [key[7:] for key in self.filters if key.startswith('filter-')]
