from app.apis.apiV1.Repository.UserRepository import  UserRepository
from app.apis.apiV1.Resourses.User.UserResourses import UserListResponse ,UserWithOutToken,UserCreated,UserInResponse
from app.apis.apiV1.Resourses.base import Response,ResponseData

from app.utilities.exceptions.http.exc_400 import (
    http_exc_400_credentials_bad_signin_request,
    http_exc_400_credentials_bad_signup_request,
)
from app.utilities.exceptions.database import EntityAlreadyExists
from app.apis.apiV1.Dependencies.repository import get_repository
import json
from passlib.context import CryptContext
import fastapi
from fastapi import APIRouter, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from datetime import datetime, timedelta
from jose import JWTError, jwt
from app.core import config

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/login")
router = APIRouter()

def index(session, skip: int = 0, limit: int = 100):
    users = UserRepository.getAll(session=session)
    return [{'id': user.id, 'username': user.username,'email': user.email}  for user in users]

def store(user,session):
    try:
        UserRepository.is_username_taken(username=user.username,session=session)
        UserRepository.is_email_taken(email=user.email,session=session)

    except EntityAlreadyExists as e:
        return fastapi.HTTPException(
        status_code=fastapi.status.HTTP_400_BAD_REQUEST,
        detail=e,
    )
    UserRepository.store(user_create=user,session=session)
    return Response(status="Ok",
                    code=fastapi.status.HTTP_201_CREATED,
                    message="User created successfully").dict(exclude_none=True)


def get_user(db, username: str):
    user= UserRepository.getByEmail(db,email=username)
    if user is None:
        return None
    else:
        return user


def authenticate_user(
    username: str,
    password: str,
    db 
) :
    user = get_user(db, username)
    if not user:
        return False
    if not verify_password(password, user.hashed_password):
        return True
    return user

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


def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str:
    to_encode = data.copy()

    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)

    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(
        to_encode,
        config.API_SECRET_KEY,
        algorithm=config.API_ALGORITHM,
    )
    return encoded_jwt