from io import BytesIO

import requests
import yaml
from django.views.generic import TemplateView
from djconfig import config
from jconfig.base import BaseConfig
from python_anticaptcha import AnticaptchaClient, ImageToTextTask
from yaml.parser import ParserError

from cabinet.utils import CabinetViewMixin
from feeds.forms import FeedForm, FeedsAppConfigForm
from config.utils import get_config_form
from feeds.models import Feed


class BaseFeedConfigView(CabinetViewMixin, TemplateView):
    template_name = 'cabinet/feeds/feed_form.html'
    context_object_name = 'feed'

    def get_queryset(self):
        return Feed.objects.filter(owner=self.request.user)

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return self.render_to_response(self.get_context_data())

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        feed_form, config_form = self.get_forms()
        if feed_form.is_valid() and config_form.is_valid():
            return self.form_valid(feed_form, config_form)
        else:
            context = self.get_context_data(forms=(feed_form, config_form))
            return self.render_to_response(context)

    def get_forms(self):
        feed = self.get_object()
        data = self.request.POST if self.request.method == 'POST' else None
        return FeedForm(data=data, instance=feed), \
               get_config_form(self.get_content_type().model_class())(data=data, instance=feed.config if feed else None)

    def get_context_data(self, forms=None, **kwargs):
        ctx = super(BaseFeedConfigView, self).get_context_data(**kwargs)
        ctx['feed_form'], ctx['config_form'] = self.get_forms() if forms is None else forms
        ctx['feed_module'] = self.get_content_type().model_class()
        return ctx


class DatabaseConfig(BaseConfig):
    __slots__ = ()

    def load(self, **kwargs):
        config._reload_maybe()
        try:
            settings = yaml.load(config.vk_auth, yaml.Loader)
            if not settings:
                settings = {}
        except (ParserError, AttributeError):
            settings = {}
        settings.setdefault(self.section_name, {})
        return settings

    def save(self):
        form = FeedsAppConfigForm(data={'vk_auth': yaml.dump(self._settings)})
        form.is_valid()
        form.save()


def captcha_handler(captcha):
    client = AnticaptchaClient(config.anticaptcha_token)
    job = client.createTask(ImageToTextTask(BytesIO(requests.get(captcha.get_url()).content)))
    job.join()
    return captcha.try_again(job.get_captcha_text())
