"""
camcops_server/tasks/khandaker_insight_medical.py

===============================================================================

    Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
    Created by Rudolf Cardinal (rnc1001@cam.ac.uk).

    This file is part of CamCOPS.

    CamCOPS 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 3 of the License, or
    (at your option) any later version.

    CamCOPS 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 CamCOPS. If not, see <https://www.gnu.org/licenses/>.

===============================================================================

"""

# =============================================================================
# Imports
# =============================================================================

from typing import Any, Type

import cardinal_pythonlib.rnc_web as ws
from sqlalchemy.sql.schema import Column
from sqlalchemy.sql.sqltypes import UnicodeText

from camcops_server.cc_modules.cc_constants import CssClass
from camcops_server.cc_modules.cc_html import (
    bold,
    get_yes_no_none,
    tr_span_col,
)
from camcops_server.cc_modules.cc_request import CamcopsRequest
from camcops_server.cc_modules.cc_sqla_coltypes import bool_column
from camcops_server.cc_modules.cc_task import Task, TaskHasPatientMixin


# =============================================================================
# Constants
# =============================================================================


class KQInfo(object):
    def __init__(self, stem: str, heading_xml: str = "") -> None:
        self.fieldname_yn = stem + "_yn"
        self.fieldname_comment = stem + "_comment"
        self.question_xmlstr = "q_" + stem
        self.heading_xmlstr = heading_xml

    def has_heading(self) -> bool:
        return bool(self.heading_xmlstr)


QUESTIONS = [
    KQInfo("cancer", "heading_cancer"),
    KQInfo("epilepsy", "heading_brain"),
    KQInfo("cva_headinjury_braintumour"),
    KQInfo("ms_pd_dementia"),
    KQInfo("cerebralpalsy_otherbrain"),
    KQInfo("visual_impairment"),
    KQInfo("heart_disorder", "heading_cardiovascular"),
    KQInfo("respiratory", "heading_respiratory"),
    KQInfo("gastrointestinal", "heading_gastrointestinal"),
    KQInfo("other_inflammatory", "heading_inflammatory"),
    KQInfo("musculoskeletal", "heading_musculoskeletal"),
    KQInfo("renal_urinary", "heading_renal_urinary"),
    KQInfo("dermatological", "heading_dermatological"),
    KQInfo("diabetes", "heading_endocrinological"),
    KQInfo("other_endocrinological"),
    KQInfo("haematological", "heading_haematological"),
    KQInfo("infections", "heading_infections"),
]

X_TITLE = "title"
X_INSTRUCTION = "instruction"
X_HEADING_CONDITION = "heading_condition"
X_HEADING_YN = "heading_yn"
X_HEADING_COMMENT = "heading_comment"
X_COMMENT_HINT = "comment_hint"


# =============================================================================
# Khandaker_1_MedicalHistory
# =============================================================================


class KhandakerInsightMedical(  # type: ignore[misc]
    TaskHasPatientMixin,
    Task,
):
    """
    Server implementation of the Khandaker_1_MedicalHistory task.
    """

    __tablename__ = "khandaker_1_medicalhistory"  # NB historical name
    shortname = "Khandaker_Insight_Medical"
    info_filename_stem = "khandaker_insight_medical"

    @classmethod
    def extend_columns(
        cls: Type["KhandakerInsightMedical"], **kwargs: Any
    ) -> None:
        for qinfo in QUESTIONS:
            setattr(cls, qinfo.fieldname_yn, bool_column(qinfo.fieldname_yn))
            setattr(
                cls,
                qinfo.fieldname_comment,
                Column(qinfo.fieldname_comment, UnicodeText),
            )

    @staticmethod
    def longname(req: "CamcopsRequest") -> str:
        _ = req.gettext
        return _("Khandaker GM — Insight — Medical history")

    def is_complete(self) -> bool:
        for qinfo in QUESTIONS:
            yn_value = getattr(self, qinfo.fieldname_yn)
            if yn_value is None:
                return False
            if yn_value:
                comment = getattr(self, qinfo.fieldname_comment)
                if not comment:
                    return False
        return True

    def get_task_html(self, req: CamcopsRequest) -> str:
        html = f"""
            <div class="{CssClass.SUMMARY}">
                <table class="{CssClass.SUMMARY}">
                    {self.get_is_complete_tr(req)}
                </table>
            </div>
            <table class="{CssClass.TASKDETAIL}">
                <tr>
                    <th width="40%">{self.xstring(req,
                                                  X_HEADING_CONDITION)}</th>
                    <th width="20%">{self.xstring(req, X_HEADING_YN)}</th>
                    <th width="40%">{self.xstring(req, X_HEADING_COMMENT)}</th>
                </tr>
        """

        for qinfo in QUESTIONS:
            if qinfo.has_heading():
                html += tr_span_col(
                    self.xstring(req, qinfo.heading_xmlstr),
                    cols=3,
                    tr_class=CssClass.SUBHEADING,
                )
            yn_value = getattr(self, qinfo.fieldname_yn)
            yn_str = get_yes_no_none(req, yn_value)
            if yn_value:
                yn_str = bold(yn_str)
            comment_value = getattr(self, qinfo.fieldname_comment)
            html += f"""
                <tr>
                    <td>{self.xstring(req, qinfo.question_xmlstr)}</td>
                    <td>{yn_str}</td>
                    <td>{bold(ws.webify(comment_value))
                         if comment_value else ""}</td>
                </tr>
            """

        html += "</table>"
        return html
