import json
import os
from flask import g
from models.customer_models import CustomerOperations, CustomerRecord
from models.call_actions_models import CallActionOperations, CallAction
from models.userModels import UserOperations, User
from models.ticket_models import TicketOperations, Ticket
from typing import List, Optional
from utilities.logging_functions import *
from models.department_models import DepartmentOperations, Department
from models.note_models import NoteOperations, Note
from models.leads_models import LeadOperations, Lead
from models.customer_view_models import CustomerViewOperations, CustomerViewModel


"""
This ile is where we define the resolvers for the GraphQL queries.
These resolvers will be used to fetch data when a query is made.

The resolvers will communicate with out backend and database to fetch the required data.
This file is imported in the schema.py file.
"""

log_file = "gql.graphql.resolvers.query_resolvers.py"


def get_portal_users(obj, info):
    return [
        {"name": "Alice", "role": "Admin"},
        {"name": "Bob", "role": "User"},
    ]


def get_status(obj, info):
    return "GQL API is working!"


def say_hello(obj, info):
    return "Hello, world!"


def get_all_users(obj, info) -> List[User]:
    """
    Resolver to fetch all users from the database.

    """

    try:

        client = g.db_client
        client._ensure_connection()

        echo_log("Fetching all users from the database.", log_file=log_file)

        user_ops = UserOperations(db_client=client)
        users = user_ops.get_all_users() or []

        echo_log(f"Retrieved {len(users)} users.", log_file=log_file)
        return users

    except Exception as e:
        echo_log(f"Error in get_all_users: {e}", log_file=log_file)
        return []


def get_customer_by_id(obj, info, id: int) -> CustomerRecord | None:
    try:
        client = g.db_client
        client._ensure_connection()

        customer_ops = CustomerOperations(db_client=client)
        customer = customer_ops.get_customer_by_id(parrams={"customer_id": id})
        if customer:
            return customer
        return None

    except Exception as e:
        echo_log(f"Error in get_customer_by_id: {e}", log_file=log_file)
        return None


def me_resolver(obj, info):
    if getattr(g, "current_user", None) is None:
        print("[ME] No current_user on g, returning None")
        return None

    print("[ME] Returning current_user:", g.current_user)
    return g.current_user


# Customers -------------------------------------------------


def get_all_customers(obj, info) -> List[CustomerRecord]:
    try:
        client = g.db_client
        client._ensure_connection()

        customer_ops = CustomerOperations(db_client=client)

        customers = customer_ops.get_all_customers()
        return customers

    except Exception as e:
        echo_log(f"Error in get_all_customers: {e}", log_file=log_file)
        return []


# Call actions -------------------------------------------------


def get_missed_calls_by_dept(obj, info, dept_id) -> List[CallAction]:
    try:
        client = g.db_client
        client._ensure_connection()

        try:
            dept_id_int = int(dept_id)
        except (TypeError, ValueError):
            echo_log(f"Invalid dept_id: {dept_id}", log_file=log_file)
            return []

        call_action_ops = CallActionOperations(db_client=client)
        missed_calls = (
            call_action_ops.get_all_call_actions_by_dept(department_id=dept_id_int)
            or []
        )

        if not missed_calls:
            echo_log(
                f"No missed calls found for department ID {dept_id_int}",
                log_file=log_file,
            )
            return []

        return missed_calls

    except Exception as e:
        echo_log(f"Error in get_missed_calls_by_dept: {e}", log_file=log_file)
        return []


def get_all_tickets_for_user(obj, info, user_id) -> List[Ticket]:
    try:
        client = g.db_client
        client._ensure_connection()

        # GraphQLID commonly comes in as str
        try:
            user_id_int = int(user_id)
        except (TypeError, ValueError):
            echo_log(f"Invalid user_id: {user_id}", log_file=log_file)
            return []  # or None if you truly want nullable

        ticket_ops = TicketOperations(db_client=client)
        tickets = ticket_ops.get_tickets_by_user_id(user_id=user_id_int)

        # Prefer empty list over null for "no results"
        return tickets or []

    except Exception as e:
        echo_log(f"Error in get_all_tickets_for_user: {e}", log_file=log_file)
        return []


def get_all_tickets_for_department(obj, info, department_id) -> List[Ticket]:

    try:
        client = g.db_client
        client._ensure_connection()

        ticket_ops = TicketOperations(db_client=client)
        tickets = ticket_ops.get_tickets_by_department_id(department_id=department_id)

        if not tickets:
            echo_log(
                f"No tickets found for department ID {department_id}", log_file=log_file
            )
            return []

        return tickets

    except Exception as e:
        echo_log(f"Error in get_all_ticket_for_department: {e}", log_file=log_file)
        return []


def get_all_departments(obj, info) -> List[Department]:
    """
    Resolver to fetch all departments.
    """
    try:
        client = g.db_client
        client._ensure_connection()

        department_ops = DepartmentOperations(db_client=client)
        departments = department_ops.get_all_departments()

        if not departments:
            echo_log("No departments found", log_file=log_file)
            return []

        return departments

    except Exception as e:
        echo_log(f"Error in get_all_departments: {e}", log_file=log_file)
        return []


def get_all_notes(obj, info) -> Optional[List[Note]]:
    """
    Resolver to fetch all notes.
    """
    try:
        client = g.db_client
        client._ensure_connection()

        note_ops = NoteOperations(db_client=client)
        notes = note_ops.get_all_notes()

        if not notes:
            echo_log("No notes found", log_file=log_file)
            return []

        return notes

    except Exception as e:
        echo_log(f"Error in get_all_notes: {e}", log_file=log_file)
        return []


def get_notes_by_customer_id(obj, info, customer_id: int) -> Optional[List[Note]]:
    """
    Resolver to fetch notes by customer ID.
    """
    try:
        client = g.db_client
        client._ensure_connection()

        note_ops = NoteOperations(db_client=client)
        notes = note_ops.get_notes_by_customer_id(customer_id=customer_id)

        if notes is None:
            echo_log(f"No notes found for customer ID {customer_id}", log_file=log_file)
            return []

        return notes

    except Exception as e:
        echo_log(f"Error in get_notes_by_customer_id: {e}", log_file=log_file)
        return []


def get_notes_by_job_id(obj, info, ff_job_id: int) -> Optional[List[Note]]:
    """
    Resolver to fetch notes by Firefly job ID.
    """
    try:
        client = g.db_client
        client._ensure_connection()

        note_ops = NoteOperations(db_client=client)
        notes = note_ops.get_notes_by_job_id(ff_job_id=ff_job_id)

        if notes is None:
            echo_log(f"No notes found for ff_job_id {ff_job_id}", log_file=log_file)
            return []

        return notes

    except Exception as e:
        echo_log(f"Error in get_notes_by_job_id: {e}", log_file=log_file)
        return []


def get_all_leads(obj, info) -> Optional[List[Lead]]:
    """
    Resolver to fetch all leads.
    """
    try:
        client = g.db_client
        client._ensure_connection()

        lead_ops = LeadOperations(db_client=client)
        leads = lead_ops.get_all_leads()

        if not leads:
            echo_log("No leads found", log_file=log_file)
            return []

        return leads

    except Exception as e:
        echo_log(f"Error in get_all_leads: {e}", log_file=log_file)
        return []


def get_customer_view_by_customer_id(
    obj, info, customer_id: int
) -> Optional[CustomerViewModel]:
    """
    Resolver to fetch customer view by customer ID.
    """
    try:
        client = g.db_client
        client._ensure_connection()

        customer_view_ops = CustomerViewOperations(db_client=client)
        customer_view = customer_view_ops.get_customer_view_by_customer_id(
            customer_id=customer_id
        )

        if not customer_view:
            echo_log(
                f"No customer view found for customer ID {customer_id}",
                log_file=log_file,
            )
            return None

        return customer_view

    except Exception as e:
        echo_log(
            f"Error in get_customer_view_by_customer_id: {e}",
            log_file=log_file,
        )
        return None
