
from django.core import paginator
from django.db import models
from django.http import HttpResponse
from django.utils.translation import gettext_lazy as _
from django.utils.functional import Promise
from accrete.contrib.ui import Filter
from .response import Response, OobResponse
from .window import WindowResponse, WindowResponseConfig


class ListResponse(WindowResponse):

    def __init__(
        self, *,
        title: str | Promise,
        context: dict,
        list_entry_template: str = None,
        page: paginator.Page = None,
        ui_filter: Filter = None,
        endless_scroll: bool = False,
        header_template: str = None,
        panel_template: str = None,
        column_count: int = 1,
        column_height: str | None = '150px',
        overview_template: str = 'ui/list.html',
        detail_header_template: str = None,
        detail_data_template: str = None,
        detail_enabled: bool = True,
        config: WindowResponseConfig = None
    ):
        assert page is not None or ui_filter is not None, _(
            'Argument page or ui_filter must be supplied'
        )
        super().__init__(
            title=title,
            context=context,
            overview_template=overview_template,
            header_template=header_template,
            panel_template=panel_template,
            config=config
        )
        self.page = page or (ui_filter and ui_filter.get_page())
        self.list_entry_template = list_entry_template
        self.ui_filter = ui_filter
        self.endless_scroll = endless_scroll
        self.column_count = column_count
        self.column_height = column_height
        self.detail_header_template = detail_header_template
        self.detail_data_template = detail_data_template
        self.detail_enabled = detail_enabled

    def _has_panel(self):
        return bool(self.panel_template or self.ui_filter)

    def get_context(self):
        context = super().get_context()
        context.update({
            'list_entry_template': self.list_entry_template,
            'page': self.page,
            'ui_filter': self.ui_filter,
            'endless_scroll': self.endless_scroll,
            'column_count': self.column_count,
            'column_height': self.column_height,
            'detail_enabled': self.detail_enabled,
            'detail_header_template': self.detail_header_template,
            'detail_data_template': self.detail_data_template,
            'show_content_right': str(bool(
                self.detail_header_template or self.detail_data_template
            )).lower(),
        })
        return context

    def response(self, request, extra_content: str = None, replace_body: bool = False) -> HttpResponse:
        return super().response(request, extra_content, replace_body)


class ListEntryResponse(Response):

    base_template = 'ui/list_update.html'

    def __init__(
        self, *,
        instance: models.Model,
        list_entry_template: str,
        context: dict = None,
        page: paginator.Page = None,
        is_new: bool = False,
        column_count: int = 1,
        column_height: str = '150px',
    ):
        super().__init__(template=self.base_template, context=context or {})
        self.instance = instance
        self.instance.refresh_from_db()
        self.list_entry_template = list_entry_template
        self.page = page
        self.is_new = is_new
        self.column_count = column_count
        self.column_height = column_height

    def get_context(self):
        context = super().get_context()
        context.update({
            'instance': self.instance,
            'list_entry_template': self.list_entry_template,
            'is_new': self.is_new,
            'column_count': self.column_count,
            'column_height': self.column_height
        })
        return context

    def render(self, request) -> str:
        res = super().render(request)
        if self.page:
            pagination_update = OobResponse(
                template='ui/layout.html#pagination',
                swap='innerHTML:#pagination',
                context=dict(page=self.page)
            ).render(request)
            res += pagination_update
        return res
