from __future__ import annotations
from datetime import datetime, timedelta
from typing import List

import jwt
from jwt.exceptions import DecodeError
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel

from app.auth import get_current_user
from app.models import Goal, User

router = APIRouter()

"""TODO
1. 구글에서 발행해주는 Id_token을 인증하는 방법
2. goalPlan 수정 api (하루치 계획를 이루었을때 사용)
"""


class IdToken(BaseModel):
    idToken: str


class GoalForm(BaseModel):
    userId: str
    goalName: str
    goalTags: List[str] = []
    plan: str
    period: int = 1
    startedAt: datetime
    howManyTimes: int


@router.post("/user", tags=["User Login"])
async def post_user(
    id_token: IdToken,
    auth: Depends = Depends(get_current_user),
):
    """사용자 로그인"""
    try:
        user_data = jwt.decode(id_token.idToken, options={"verify_signature": False})
    except DecodeError as e:
        return HTTPException(status_code=400, detail=f"jwt is not valid : {e}")

    user = User.find_by_email(user_data["email"])
    print(user)
    if not user:
        _id = User.insert_one(user_data)
        detail = "new user"
    else:
        _id = user["_id"]
        detail = "old user"
    return {"_id": _id, "detail": detail}


@router.get("/user", tags=["User Detail"])
async def get_detail_user(
    user_id: str,
    # auth: Depends = Depends(get_current_user),
):
    """유저 정보 조회"""
    user = User.find_by_id(user_id)
    if not user:
        return HTTPException(
            status_code=400, detail=f"Not Found User ID in DB : {user_id}"
        )
    return user


@router.post("/goal", tags=["Goal Register"])
async def post_goal(
    goal: GoalForm,
    #     auth: Depends = Depends(get_current_user),
):
    """
    목표 등록

    Todo
    ------
    해당 목표를 언제까지 또는 몇번 수행하겠다는 정보가 없다. 즉, plan 의 갯수를 계산할 수 없다.


    Param
    ----------------------------
        userId: user id
        goalName: 목표 제목
        goalTags: 목표 태그
        plan: 계획
        period: 반복 주기
        howManyTimes : 반복 횟수
        startedAt: 목표 시작일 ex) yyyy-mm-ddThh:mm

    return
    ----------------------------
        goal_id
    """
    user = User.find_by_id(goal.userId)
    if not user:
        return HTTPException(
            status_code=400, detail=f"Not Found User ID in DB : {goal.userId}"
        )
    """
        planDone :
            {
            deadline : 20xx-xx-xx,
            status : success/ faill/ wait,
            id : int, start with 0
            }
    """
    planDone = [
        {
            "deadline": goal.startedAt + timedelta(i * goal.period),
            "id": i,
            "status": "wait",
        }
        for i in range(goal.howManyTimes)
    ]
    dict_goal = dict(goal)
    dict_goal["planDone"] = planDone
    dict_goal["deadline"] = planDone[-1]["deadline"]
    del dict_goal["howManyTimes"]
    del dict_goal["period"]
    del dict_goal["startedAt"]
    _id = Goal.insert_one(dict_goal)
    return {"_id": _id}


@router.get("/goal/{goal_id}", tags=["Goal Detail"])
async def get_detail_goal(
    goal_id: str,
    auth: Depends = Depends(get_current_user),
):
    """목표 상세 조회"""

    goal = Goal.find_by_id(goal_id)
    if not goal:
        return HTTPException(
            status_code=400, detail=f"not found goal_id in db : {goal_id}"
        )

    res = Goal.find_by_id(goal_id)
    return res


@router.get("/user/{user_id}/goals", tags=["Goal List of user's"])
async def get_user_goal(
    user_id: str,
    auth: Depends = Depends(get_current_user),
):
    """개인 목표 조회"""
    user = User.find_by_id(user_id)
    if not user:
        return HTTPException(
            status_code=400, detail=f"not found user_id in db : {user_id}"
        )

    res = Goal.find_by_user_id(user_id)
    return res


@router.delete("/goal/{goal_id}", tags=["Goal Delete"])
async def delete_goal(goal_id: str, auth: Depends = Depends(get_current_user)):
    """개인 목표 삭제"""
    res = Goal.delete_by_id(goal_id)
    return res

from __future__ import annotations
from datetime import datetime, timedelta
from typing import List

import jwt
from jwt.exceptions import DecodeError
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel

from app.auth import get_current_user
from app.models import Goal, User

router = APIRouter()

"""TODO
1. 구글에서 발행해주는 Id_token을 인증하는 방법
2. goalPlan 수정 api (하루치 계획를 이루었을때 사용)
"""


class IdToken(BaseModel):
    idToken: str


class GoalForm(BaseModel):
    userId: str
    goalName: str
    goalTags: List[str] = []
    plan: str
    period: int = 1
    startedAt: datetime
    howManyTimes: int


@router.post("/user", tags=["User Login"])
async def post_user(
    id_token: IdToken,
    auth: Depends = Depends(get_current_user),
):
    """사용자 로그인"""
    try:
        user_data = jwt.decode(id_token.idToken, options={"verify_signature": False})
    except DecodeError as e:
        return HTTPException(status_code=400, detail=f"jwt is not valid : {e}")

    user = User.find_by_email(user_data["email"])
    print(user)
    if not user:
        _id = User.insert_one(user_data)
        detail = "new user"
    else:
        _id = user["_id"]
        detail = "old user"
    return {"_id": _id, "detail": detail}


@router.get("/user", tags=["User Detail"])
async def get_detail_user(
    user_id: str,
    # auth: Depends = Depends(get_current_user),
):
    """유저 정보 조회"""
    user = User.find_by_id(user_id)
    if not user:
        return HTTPException(
            status_code=400, detail=f"Not Found User ID in DB : {user_id}"
        )
    return user


@router.post("/goal", tags=["Goal Register"])
async def post_goal(
    goal: GoalForm,
    #     auth: Depends = Depends(get_current_user),
):
    """
    목표 등록

    Todo
    ------
    해당 목표를 언제까지 또는 몇번 수행하겠다는 정보가 없다. 즉, plan 의 갯수를 계산할 수 없다.


    Param
    ----------------------------
        userId: user id
        goalName: 목표 제목
        goalTags: 목표 태그
        plan: 계획
        period: 반복 주기
        howManyTimes : 반복 횟수
        startedAt: 목표 시작일 ex) yyyy-mm-ddThh:mm

    return
    ----------------------------
        goal_id
    """
    user = User.find_by_id(goal.userId)
    if not user:
        return HTTPException(
            status_code=400, detail=f"Not Found User ID in DB : {goal.userId}"
        )
    """
        planDone :
            {
            deadline : 20xx-xx-xx,
            status : success/ faill/ wait,
            id : int, start with 0
            }
    """
    planDone = [
        {
            "deadline": goal.startedAt + timedelta(i * goal.period),
            "id": i,
            "status": "wait",
        }
        for i in range(goal.howManyTimes)
    ]
    dict_goal = dict(goal)
    dict_goal["planDone"] = planDone
    dict_goal["deadline"] = planDone[-1]["deadline"]
    del dict_goal["howManyTimes"]
    del dict_goal["period"]
    del dict_goal["startedAt"]
    _id = Goal.insert_one(dict_goal)
    return {"_id": _id}


@router.get("/goal/{goal_id}", tags=["Goal Detail"])
async def get_detail_goal(
    goal_id: str,
    auth: Depends = Depends(get_current_user),
):
    """목표 상세 조회"""

    goal = Goal.find_by_id(goal_id)
    if not goal:
        return HTTPException(
            status_code=400, detail=f"not found goal_id in db : {goal_id}"
        )

    res = Goal.find_by_id(goal_id)
    return res


@router.get("/user/{user_id}/goals", tags=["Goal List of user's"])
async def get_user_goal(
    user_id: str,
    auth: Depends = Depends(get_current_user),
):
    """개인 목표 조회"""
    user = User.find_by_id(user_id)
    if not user:
        return HTTPException(
            status_code=400, detail=f"not found user_id in db : {user_id}"
        )

    res = Goal.find_by_user_id(user_id)
    return res


@router.delete("/goal/{goal_id}", tags=["Goal Delete"])
async def delete_goal(goal_id: str, auth: Depends = Depends(get_current_user)):
    """개인 목표 삭제"""
    res = Goal.delete_by_id(goal_id)
    return res

TODO 1. 구글에서 발행해주는 Id_token을 인증하는 방법 2. goalPlan 수정 api (하루치 계획를 이루었을때 사용) 사용자 로그인 # auth: Depends = Depends(get_current_user), 유저 정보 조회 #     auth: Depends = Depends(get_current_user), 목표 등록      Todo     ------     해당 목표를 언제까지 또는 몇번 수행하겠다는 정보가 없다. 즉, plan 의 갯수를 계산할 수 없다.       Param     ----------------------------         userId: user id         goalName: 목표 제목         goalTags: 목표 태그         plan: 계획         period: 반복 주기         howManyTimes : 반복 횟수         startedAt: 목표 시작일 ex) yyyy-mm-ddThh:mm      return     ----------------------------         goal_id planDone :             {             deadline : 20xx-xx-xx,             status : success/ faill/ wait,             id : int, start with 0             } 목표 상세 조회 개인 목표 조회 개인 목표 삭제