# -*- coding: utf-8 -*-
import logging

from events.common_app.wiki import get_wiki_client
from events.data_sources.filters import ListOrCommaSeparatedStringListFilter
from events.data_sources.sources.external_table.base import (
    BaseExternalTableDataSource,
    BaseExternalTableDataSourceFilter,
)

logger = logging.getLogger(__name__)


class WikiDataSourceFilter(BaseExternalTableDataSourceFilter):
    id = ListOrCommaSeparatedStringListFilter(name='id')

    def get_column_order(self, table_data):
        columns = {
            column['title']: i
            for i, column in enumerate(table_data['structure']['fields'])
        }
        return columns['name'], columns.get('parent')

    def _suggested(self, row, name_column):
        return (
            not self.suggest
            or self.suggest in row[name_column]['raw'].lower()
        )

    def _fits_filter_by_question(self, row, parent_column, filter_by_question):
        return (
            not filter_by_question
            or (
                parent_column
                and filter_by_question.split('_')[-1] == str(row[parent_column]['raw'])
            )
        )

    def _fits_filter_by_id(self, id_to_check, ids):
        if not ids or ids == id_to_check:
            return True
        for _id in ids:
            if id_to_check == _id:
                return True
        return False

    def _get_external_data(self, url):
        client = get_wiki_client(self.filter_data.get('dir_id'))
        supertag = client.get_supertag(url)
        if supertag:
            table_data = client.get_table_data(supertag)
            name_column, parent_column = self.get_column_order(table_data)
            filter_by_question = self.filter_data.get(WikiDataSource.name)
            result = [
                {
                    'id': str(i),
                    'name': row[name_column]['raw']
                }
                for i, row in enumerate(table_data['rows'], start=1)
                if (
                    self._suggested(row, name_column)
                    and self._fits_filter_by_question(row, parent_column, filter_by_question)
                    and self._fits_filter_by_id(str(i), self.ids_passed)
                )
            ]
            suggest_sort_key = lambda x: (len(x['name']), x['name'])
            name_sort_key = lambda x: x['name']
            if self.suggest:
                result = sorted(result, key=suggest_sort_key)
            else:
                result = sorted(result, key=name_sort_key)
            return result

    def _get_data(self, url):
        try:
            return self._get_external_data(url)
        except Exception as e:
            logger.warn('Wiki Error: %s', e)

    @staticmethod
    def declared_filters():
        return {
            WikiDataSource.name: WikiDataSource
        }


class WikiDataSource(BaseExternalTableDataSource):
    name = 'wiki_table_source'
    data_source = name
    title = 'Таблицы Wiki'
    desc = 'Данные из произвольной таблицы Wiki'
    filter_class = WikiDataSourceFilter
