import json
import logging
from datetime import datetime
from peewee import JOIN
from flask_jwt_extended import jwt_required

from flask import Blueprint, request
from median.constant import EcoType
from median.models import ListeItemModel, ListeModel, WorkItemModel

from common.models import WebLogActions
from common.status import (
    HTTP_200_OK,
    HTTP_500_INTERNAL_SERVER_ERROR,
)

from common.util import mustHaveRights
from playhouse.shortcuts import model_to_dict

tools_workitems = Blueprint("tools_workitems", __name__)

logger = logging.getLogger("tools.workitems")

RESSOURCE_NAME = "WEB_ADMINISTRATION"


@tools_workitems.route("", methods=["POST"])
@jwt_required()
@mustHaveRights(RESSOURCE_NAME, canView=True)
def get_work_items():
    try:
        data = json.loads(request.data)

        # Pagination parameters
        page = int(data.get("page", 1))
        rowsPerPage = int(data.get("rowsPerPage", 20))
        sortBy = data.get("sortBy", "id")
        descending = data.get("descending", False)

        query = (
            WorkItemModel.select(WorkItemModel, ListeModel.zone_deb, ListeModel.zone_fin)
            .join(ListeItemModel, JOIN.INNER, on=(ListeItemModel.pk == WorkItemModel.pk_item))
            .join(
                ListeModel,
                JOIN.INNER,
                on=((ListeModel.liste == WorkItemModel.liste) & (ListeModel.mode == WorkItemModel.mode)),
            )
        )

        if "liste" in data:
            query = query.where(WorkItemModel.liste == data["liste"])
        if "mode" in data:
            query = query.where(WorkItemModel.mode == data["mode"])
        if "item" in data:
            query = query.where(WorkItemModel.item == data["item"])
        if "reference" in data:
            query = query.where(WorkItemModel.reference == data["reference"])
        if "zone_deb" in data:
            query = query.where(ListeModel.zone_deb == data["zone_deb"])
        if "zone_fin" in data:
            query = query.where(ListeModel.zone_fin == data["zone_fin"])

        total_count = query.count()

        # Apply sorting
        if hasattr(WorkItemModel, sortBy):
            sort_field = getattr(WorkItemModel, sortBy)
            if descending:
                query = query.order_by(sort_field.desc())
            else:
                query = query.order_by(sort_field)

        # Apply pagination
        if rowsPerPage > 0:
            query = query.paginate(page, rowsPerPage)

        # Convert to dict and exclude fields if needed
        exclude = [WorkItemModel.alveole, WorkItemModel.alveole_theo]

        workitems_dict = []
        for wi in query:
            wi_dict = model_to_dict(wi, exclude=exclude)
            # Add zone_deb and zone_fin from ListeModel using the aliases
            wi_dict["liste_zone_deb"] = wi.listeitemmodel.listemodel.zone_deb
            wi_dict["liste_zone_fin"] = wi.listeitemmodel.listemodel.zone_fin
            workitems_dict.append(wi_dict)

        return {
            "data": workitems_dict,
            "pagination": {
                "page": page,
                "rowsPerPage": rowsPerPage,
                "rowsNumber": total_count,
                "sortBy": sortBy,
                "descending": descending,
            },
        }, HTTP_200_OK

    except Exception as e:
        logger.error(f"Error fetching work items: {str(e)}")
        return {"error": str(e)}, HTTP_500_INTERNAL_SERVER_ERROR


def log_work_items(username: str, action: str, message: str):
    """
    Add new log for work_items

    :param username: User made the action to log
    :param action:
    :param message: message to log
    """
    logger.info("[%s](%s)): %s" % (action, username, message))
    wlog = WebLogActions()
    wlog.chrono = datetime.now()
    wlog.username = username
    wlog.equipement_type = EcoType.Externe.value
    wlog.action = action
    wlog.message = message
    wlog.save()
