from datetime import datetime
import json
import pathlib
from typing import Annotated
from fastapi import APIRouter, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from app.api.auth import service
from app.database.main.mysql import get_db
from app.dependency.authantication import JWTManager
from app.models.main.admin import TblAdmin
from app.models.main.role import TblRole
from app.models.main.seafarer import TblSeafarers
from app.models.main.seafarer_id_type import TblSeafarerIdType
from app.models.main.seafarer_role import TblSeafarerRole
from app.models.main.user_otp import TblUserOTP
from app.models.main.users import TblUsers
from app.utils.email_utils import send_email
from app.utils.schemas_utils import CustomResponse
from .schemas import SeafarerRoleCreate, SeafarererRoleUpdate, UserCreate,UserUpdate
import secrets
import string
from passlib.context import CryptContext

auth_router = APIRouter()

@auth_router.post("/auth",response_model_exclude_none=True)
async def create_admin(request: UserCreate,db:Session=Depends(get_db), token: dict = Depends(JWTManager.verify_token)):
    return await service.AuthService(db,token).create_user(request)

@auth_router.put("/auth",response_model_exclude_none=True)
async def update_admin(request: UserUpdate,db:Session=Depends(get_db),token: dict = Depends(JWTManager.verify_token)):
    return await service.AuthService(db,token).update_user(request)

@auth_router.post("/user/login")
async def login_user(credentials: Annotated[OAuth2PasswordRequestForm, Depends()],db: Session = Depends(get_db)):
    return await service.AuthService(db, token={}).user_login(credentials)

@auth_router.post("/Seafarer-role",response_model_exclude_none=True)
async def create_role(request: SeafarerRoleCreate,db:Session=Depends(get_db), token: dict = Depends(JWTManager.verify_token)):
    return await service.AuthService(db,token).create_role(request)

@auth_router.get("/Seafarer-roles", response_model_exclude_none=True)
async def get_all_roles(db: Session = Depends(get_db), token: dict = Depends(JWTManager.verify_token)):
    return await service.AuthService(db, token).get_all_roles()

@auth_router.put("/Seafarer-role/{sf_role_id}", response_model_exclude_none=True)
async def update_role(request: SeafarererRoleUpdate, db: Session = Depends(get_db), token: dict = Depends(JWTManager.verify_token)):
    return await service.AuthService(db, token).update_role(request)

@auth_router.post("/load-roles-from-file/")
def load_roles_from_file(db: Session = Depends(get_db)):
    file_path = pathlib.Path("data/roles.json")
    if not file_path.exists():
        raise HTTPException(status_code=404, detail="roles.json not found")
    with open(file_path, "r") as file:
        roles_data = json.load(file)
    for role in roles_data:
        db_role = TblRole(role_id=role["role_id"], role_name=role["role_name"])
        db.add(db_role)
    try:
        db.commit()
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=400, detail=str(e))
    return {"message": "Roles loaded from JSON and inserted successfully."}

@auth_router.post("/load-seafarer-roles-from-file/")
def load_seafarer_roles_from_file(db: Session = Depends(get_db)):
    file_path = pathlib.Path("data/sf_roles.json")
    if not file_path.exists():
        raise HTTPException(status_code=404, detail="sf_roles.json not found")
    with open(file_path, "r") as file:
        roles_data = json.load(file)
    for role in roles_data:
        db_role = TblSeafarerRole(sf_role_id=role["sf_role_id"], sf_role_name=role["sf_role_name"])
        db.add(db_role)
    try:
        db.commit()
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=400, detail=str(e))
    return {"message": "Seafarer Roles loaded from JSON and inserted successfully."}

@auth_router.post("/load-seafarer-id-type-from-file/")
def load_seafarer_ID_type_from_file(db: Session = Depends(get_db)):
    file_path = pathlib.Path("data/sf_id_type.json")
    if not file_path.exists():
        raise HTTPException(status_code=404, detail="sf_id_type.json not found")
    with open(file_path, "r") as file:
        roles_data = json.load(file)
    for role in roles_data:
        db_role = TblSeafarerIdType(id_type=role["id_type"], sf_id_type=role["sf_id_type"])
        db.add(db_role)
    try:
        db.commit()
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=400, detail=str(e))
    return {"message": "Seafarer Roles loaded from JSON and inserted successfully."}


# @auth_router.post("/forgot-password")
# async def forgot_password(username: str, db: Session = Depends(get_db)):
#     user = db.query(TblUsers).filter(TblUsers.user_name == username).first()
#     if not user:
#         return CustomResponse(status="0", message="User not found")
#     otp = str(random.randint(100000, 999999))
#     expiry = datetime.utcnow() + timedelta(minutes=10)
#     user_otp = TblUserOTP(usr_id=user.usr_id, otp=otp, expiry=expiry)
#     db.add(user_otp)
#     db.commit()
#     send_email(to=user.user_name, subject="Password Reset OTP", body=f"Your OTP is {otp}")
#     return CustomResponse(status="1", message="OTP sent to your email")

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def hash_password(password: str) -> str:
    return pwd_context.hash(password)

def verify_password(plain_password: str, hashed_password: str) -> bool:
    return pwd_context.verify(plain_password, hashed_password)


@auth_router.post("/reset-password")
async def reset_password(username: str, otp: str, new_password: str, db: Session = Depends(get_db)):
    user = db.query(TblUsers).filter(TblUsers.user_name == username).first()
    if not user:
        return CustomResponse(status="0", message="User not found")
    otp_entry = (
        db.query(TblUserOTP).filter(
            TblUserOTP.usr_id == user.usr_id,
            TblUserOTP.otp == otp,
            TblUserOTP.expiry >= datetime.utcnow()
        )
        .first()
    )
    if not otp_entry:
        return CustomResponse(status="0", message="Invalid or expired OTP")
    user.password = new_password
    if user.role_id in {1, 2, 3}:
        admin = db.query(TblAdmin).filter(TblAdmin.admin_id == user.entity_id).first()
        if admin:
            admin.pass_word = new_password
    elif user.role_id == 4:
        seafarer = db.query(TblSeafarers).filter(TblSeafarers.seafarer_id == user.entity_id).first()
        if seafarer:
            seafarer.password = new_password
    db.commit()
    return CustomResponse(status="1", message="Password reset successfully")

def generate_random_password(length: int = 10) -> str:
    chars = string.ascii_letters + string.digits
    return ''.join(secrets.choice(chars) for _ in range(length))


@auth_router.post("/forgot-password11")
async def forgot_password1(username: str, db: Session = Depends(get_db)):
    user = db.query(TblUsers).filter(TblUsers.user_name == username).first()
    if not user:
        return CustomResponse(status="0", message="User not found")
    new_password = generate_random_password(12)
    user.password = new_password
    if user.role_id in {1, 2, 3}:
        admin = db.query(TblAdmin).filter(TblAdmin.admin_id == user.entity_id).first()
        if admin:
            admin.pass_word = new_password
            email_to = admin.email_id
        else:
            email_to = user.user_name
    elif user.role_id == 4:
        seafarer = db.query(TblSeafarers).filter(TblSeafarers.seafarer_id == user.entity_id).first()
        if seafarer:
            seafarer.password = new_password
            email_to = seafarer.email or user.user_name
        else:
            email_to = user.user_name
    else:
        email_to = user.user_name
    db.commit()
    send_email(
        to=email_to,
        subject="Your New Password",
        body=f"Hello,\n\nYour password has been reset automatically.\n\nNew Password: {new_password}\n\nPlease log in and change it immediately."
    )
    return CustomResponse(status="1", message="A new password has been sent to your email")




