"""
_____________________________________________________________________.

:PROJECT: LARAsuite

*lara_django_base views *

:details: lara_django_base views module.
         - add app specific urls here
         -
:authors: mark doerr <mark.doerr@uni-greifswald.de>

________________________________________________________________________
"""

from configparser import ConfigParser, NoOptionError, NoSectionError
from dataclasses import dataclass, field
from typing import List

from django.http import HttpResponseRedirect
import environ
from distutils.log import debug
from django import __version__ as django_version
from django.apps import apps
from django.conf import settings
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import redirect, render
from django.urls import reverse_lazy
from django.views import generic
from django.views.generic import CreateView, DeleteView, DetailView, ListView, TemplateView, UpdateView
from django_tables2 import SingleTableView
from lara_django_people.views import PeopleMenu
from lara_django_projects.models import Experiment, Project

from . import __version__
from .forms import AddressCreateForm, AddressUpdateForm
from .models import Address
from .tables import AddressTable


@dataclass
class ItemMenu:
    menu_items: List[dict] = field(
        default_factory=lambda: [
            {"name": "item1", "path": "lara_django_base:view1-name"},
            {"name": "item2", "path": "lara_django_base:view2-name"},
        ]
    )

@dataclass
class SidebarMenu:
    menu_items: List[dict] = field(
        default_factory=lambda: [
            {"name": "Home", "path": "/", "icon": "home", "hover_class": "hover:bg-gray-500"},
            {"name": "Dashboard", "path": "/dashboard/", "icon": "dashboard", "hover_class": "hover:bg-gray-500"},
            {"name": "Apps", "path": "/apps/", "icon": "apps", "hover_class": "hover:bg-gray-500"},
            {"name": "Projects", "path": "/projects/", "icon": "projects", "hover_class": "hover:bg-red-500"},
            {"name": "Processes", "path": "/processes/", "icon": "processes", "hover_class": "hover:bg-orange-500"},
            {"name": "Data", "path": "/data/", "icon": "data", "hover_class": "hover:bg-sky-500"},
            {"name": "Devices", "path": "/material-store/device/list/", "icon": "devices", "hover_class": "hover:bg-amber-500"},
            {"name": "Parts", "path": "/material-store/part/list/", "icon": "parts", "hover_class": "hover:bg-amber-500"},
            {
                "name": "Labware",
                "path": "/material-store/labware/list/",
                "icon": "labware",
                "hover_class": "hover:bg-amber-500",
            },
            {"name": "Substances", "path": "/substances-store/", "icon": "substances", "hover_class": "hover:bg-teal-500"},
            {"name": "Organisms", "path": "/organisms-store/", "icon": "organisms", "hover_class": "hover:bg-lime-500"},
            {"name": "People", "path": "/people/", "icon": "people", "hover_class": "hover:bg-blue-500"},
        ]
    )


class BaseTemplateSettingsMixin:
    """Mixin to provide common template settings for project views."""

    def get_context_data(self, **kwargs):  # noqa: D102
        context = super().get_context_data(**kwargs)
        projects = Project.objects.exclude(parent=None)
        context["projects"] = projects
        context["projects_latest"] = projects.order_by("-datetime_last_modified")  # projects_latest
        context["menu_items"] = []  # ItemMenu().menu_items
        context["app_color"] = "gray"
        context["sidebar_menu_items"] = SidebarMenu().menu_items
        # context["sparql_server_url"] = f"http://{settings.VIRTUOSO_HOST}:{settings.VIRTUOSO_ADMIN_PORT}/sparql/"

        return context


def app_version(app):
    try:
        return __import__(app).__version__
    except AttributeError:
        return "version unknown"


env = environ.Env(
    # set casting, default value
    DEBUG=(bool, False)
)


def select_home_view(request):
    # get the user, who is currently logged in

    current_user = request.user

    user = {
        "current_user": current_user,
        "authenticated": current_user.is_authenticated,
        "home_screen_url": current_user.home_screen_url,
    }

    context = {
        "user": user,
    }

    defaut_home_screen_url = (
        current_user.home_screen_url
        if current_user.home_screen_url is not None and current_user.home_screen_url != ""
        else "lara_django_base:dashboard"
    )

    return redirect(defaut_home_screen_url)


class ChatView(BaseTemplateSettingsMixin,TemplateView):
    template_name = "lara_django_base/chat.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = "Chat"
        return context

class JupyterLiteUIView(BaseTemplateSettingsMixin,TemplateView):
    template_name = "lara_django_base/jupyter_lite_ui.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = "Jupyter Lite UI"
        return context

class SparqlUIView(BaseTemplateSettingsMixin,TemplateView):
    template_name = "lara_django_base/sparql_ui.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = "SPARQL UI"
        return context

class PrefectUIView(BaseTemplateSettingsMixin,TemplateView):
    template_name = "lara_django_base/prefect_ui.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = "Prefect UI"
        return context

class ZoteroUIView(BaseTemplateSettingsMixin,TemplateView):
    template_name = "lara_django_base/zotero_ui.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = "Zotero UI"
        return context

# influxdb data monitor view and grafana views

class InfluxDBView(BaseTemplateSettingsMixin,TemplateView):
    template_name = "lara_django_base/influxdb_ui.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = "InfluxDB UI"
        return context

class GrafanaUIView(BaseTemplateSettingsMixin,TemplateView):
    template_name = "lara_django_base/grafana_ui.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = "Grafana UI"
        return context

def add_data_monitor(request):
    if request.method == "POST":
        # Handle the form submission
        pass
    return render(request, "404.html")

class Dashboard(BaseTemplateSettingsMixin, TemplateView):
    """Dashboard class view."""

    template_name = "lara_django_base/dashboard.html"

    def get_context_data(self, **kwargs):  # noqa: D102
        context = super().get_context_data(**kwargs)

        context["title"] = "Dashboard"

        return context


class AppsSelector(BaseTemplateSettingsMixin, TemplateView):
    """Apps selector class view."""

    template_name = "lara_django_base/apps.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        lara_apps = []

        for app in apps.get_app_configs():
            try:
                lara_apps.append(
                    {
                        "name": app.verbose_name_short,
                        "description": app.lara_app_description,
                        "icon": app.lara_app_icon,
                        "color": app.lara_app_color,
                        "class_apps": app.lara_class_apps,
                        "instance_apps": app.lara_instance_apps,
                    }
                )
            except AttributeError as err:
                pass

        context["apps"] = sorted(lara_apps, key=lambda app: app["name"])

        context["sparql_server_url"] = f"http://{settings.VIRTUOSO_HOST}:{settings.VIRTUOSO_ADMIN_PORT}/sparql/"
        return context


class Home(TemplateView):
    # class HomeMenu(TemplateView):
    template_name = "lara_django_base/index.html"

    login_url = "accounts/login"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["menu_items"] = [  # {'name': 'Material', 'path': 'lara_django_material:part-list'},
            #  {'name': 'Devices',
            #      'path': 'lara_django_material:device-list'},
            #  {'name': 'Part',
            #      'path': 'lara_django_material:part-list'},
            #  {'name': 'Labware',
            #   'path': 'lara_django_material:labware-list'},
            #  {'name': 'Substances',
            #   'path': 'lara_django_material:labware-list'}
        ]
        # context['sparql_server_url'] = f'http://{settings.VIRTUOSO_HOST}:{settings.VIRTUOSO_ADMIN_PORT}/sparql/'
        return context


class AboutView(TemplateView):
    template_name = "lara_django_base/about.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        django_env = env("DJANGO_SETTINGS_MODULE")

        django_envs = {
            "lara_django.settings.development": "DEVELOPMENT",
            "lara_django.settings.production": "PRODUCTION",
            "lara_django.settings.staging": "STAGING",
        }

        try:
            django_environment = django_envs[django_env]
        except KeyError:
            django_environment = "UNKNOWN"

        # context["apps"] =

        context["lara_env"] = {
            "lara_version": __version__,
            "django_version": django_version,
            "lara_description": "The LARA-django is the comprehensive science database for the LARA suite",
            "django_environment": django_environment,
            "django_settings": django_env,
            "lara_authors": ["mark doerr (mark.doerr@uni-greifswald.de)", "benjamin lear"],
            "apps": [{"name": app, "version": app_version(app)} for app in settings.INSTALLED_APPS],
        }
        return context


class ContactView(TemplateView):
    template_name = "lara_django_base/contact.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)


class SignUp(generic.CreateView):
    form_class = UserCreationForm
    success_url = reverse_lazy("login")
    template_name = "signup.html"


class AddressDetailView(DetailView):
    model = Address

    template_name = "lara_django_people/address_detail.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["section_title"] = "Address - Details"
        context["update_link"] = "lara_django_people:address-update"
        context["menu_items"] = PeopleMenu().menu_items
        return context


class AddressesListView(SingleTableView):
    model = Address
    table_class = AddressTable

    template_name = "lara_django_people/list.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["section_title"] = "Addresses - List"
        context["create_link"] = "lara_django_people:address-create"
        context["menu_items"] = PeopleMenu().menu_items
        return context


class AddressCreateView(CreateView):
    model = Address
    template_name = "lara_django_people/create_form.html"
    form_class = AddressCreateForm
    success_url = "/people/addresses/list"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["section_title"] = "Address - Creation"
        return context

    def form_valid(self, form):
        print("**** form val")
        if "cancel" in self.request.POST:
            return HttpResponseRedirect(self.get_success_url())
        return super().form_valid(form)


class AddressUpdateView(UpdateView):
    model = Address
    template_name = "lara_django_people/update_form.html"
    form_class = AddressUpdateForm
    success_url = "/people/addresses/list"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["section_title"] = "Address - Update"
        context["delete_link"] = "lara_django_people:address-delete"

        return context


class AddressDeleteView(DeleteView):
    model = Address
    template_name = "lara_django_people/delete_form.html"
    success_url = "/people/addresses/list"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["section_title"] = "Address - Delete"
        context["delete_link"] = "lara_django_people:address-delete"
        return context
