from fastapi import APIRouter, Depends, HTTPException, status,BackgroundTasks
from datetime import datetime, timedelta,timezone,date

from src.company_management.model import Ticket
from src.core.database import get_db
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import desc, func, select
from src.auth.utils import pwd_context
from sqlalchemy import update
#external services
from src.external.email import transporter
#models
from src.models.company import Company
from src.models.company_user import User
from src.models.application_user import ApplicationUser
from sqlalchemy.orm import selectinload
#schemas
from .schemas import AddUserRequest
from src.company_management.model import Ticket

#global schemas
from src.schemas.application_user import CurrentApplicationUser

#global deps

from src.common.dependencies import get_current_application_user


#constants
from src.constants import CompanyPlanEnum

#services
from src.Service.applicationservice import ApplicationService


class ApplicationManagement(ApplicationService):
    
    @staticmethod
    async def add_user(user_info:AddUserRequest,db:AsyncSession):

        stmt = select(ApplicationUser).where(ApplicationUser.email == user_info.email).limit(1)
        result = await db.execute(stmt)
        existing_user = result.scalars().first()

        if existing_user:
            raise HTTPException(status_code=400, detail="Email already registered")
        
        applicationUser = ApplicationUser(
        email=user_info.email,
        hashed_password=pwd_context.hash(user_info.password),
        full_name=user_info.full_name,
        role=user_info.role,
        is_2FA_required=user_info.is_2FA_required,
     
        )
        db.add(applicationUser)
        await db.commit()
        await db.refresh(applicationUser)

        return {
            "message":"Application user added",
            "user":applicationUser
            }
    @staticmethod
    async def searchtickets(title:str,Issuetype:str,priority:str,db):
        '''
        search tickets based on title, issue type and priority
        args:
        title : title of the ticket
        Issuetype : issue type of the ticket
        priority : priority of the ticket
        db : database session
        returns:
        list of tickets matching the search criteria
        '''
        filter=[]
        try:
            if title:
                filter.append(Ticket.title.ilike(f"%{title}%"))
            if Issuetype:
                filter.append(Ticket.Issue_Type == Issuetype)
            if priority:
                filter.append(Ticket.priority == priority)
            smt=select(Ticket).filter(*filter).order_by(Ticket.created_at,Ticket.updated_at)
            result = await db.execute(smt)
            tickets = result.scalars().all()

            return tickets
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))
    @classmethod
    async def get_ticket_alluser(cls,page:int,limit:int,title:str,Issuetype:str,priority:str,db:AsyncSession):
        '''
        get all tickets of all users
        args:
        page : page number
        limit : limit of the records per page
        db : database session
        returns:
        ticket details of all users based on pagination
        '''
        try:
            stmt=select(Ticket)
            offset = (page - 1) * limit
            filter=[]
            if title:
                    filter.append(Ticket.title.ilike(f"%{title}%"))
            if Issuetype:
                    filter.append(Ticket.issue_type == Issuetype)
            if priority:
                    filter.append(Ticket.priority == priority)
            
            if filter:
                stmt =stmt.filter(*filter)
            # Count total for pagination
            count_stmt = select(func.count()).select_from(stmt.subquery())
            total_result = await db.execute(count_stmt)
            total = total_result.scalar_one()

                
            smt=stmt.options(selectinload(Ticket.attachments)).order_by(desc(Ticket.created_at) , desc(Ticket.updated_at)).offset(offset).limit(limit)
            result=await db.execute(smt)
            fetched_tickets=result.scalars().all()
            total_pages = (total + limit - 1) // limit
            has_next = page * limit < total
            
            
            return {
                "tickets": fetched_tickets,
                "has_next": has_next,
                "total_pages": total_pages,
            }
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))

        

    @staticmethod
    async def update_ticket_status(status:str,ticket_id:str,db:AsyncSession):
        '''
        update ticket status
        args:
        status : status of the ticket
        ticket_id : id of the ticket
        db : database session
        returns:
        ticket details
        '''
        try:
            stmt = update(Ticket).where(Ticket.ticket_id == ticket_id).values(status=status)
            result = await db.execute(stmt)
            print(f"Rows affected: {result.rowcount}")
            await db.commit()
        except Exception as e:
            print("Error while updating ticket:", e)
        #reset_link = f"https://example.com/reset-password/{encrypted_token}"

        # transporter.connect()
        # transporter.send(
        #     user.email,
        #     "Password Reset Request",
        #     f"Hi {user.full_name},\n\nClick the link below to reset your password:\n{reset_link}\n\nThis link will expire in 10 minutes."
        # )
        # transporter.close()
        return {"message":"status updated"}


