from collections import defaultdict
from datetime import datetime, timedelta
from time import time

from fastapi import APIRouter

from app import mongo
from app.utils.response_util import response

router = APIRouter()


@router.post("/get-records", tags=[""])
async def get_time_tracking_records(params: dict):
    start_time = time()

    input_date = datetime.strptime(params["date"], "%Y-%m-%dT%H:%M:%S.%f")
    month_start = input_date.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
    next_month = (month_start.replace(day=28) + timedelta(days=4)).replace(day=1)

    users = await mongo.users_collection.find({}, {"_id": False}).to_list(length=None)
    users_by_id = {
        user["id"]: user
        for user in users
    }

    records = await mongo.time_tracking_collection.find({
        "date": {
            "$gte": month_start.strftime("%Y-%m-%dT00:00:00.000"),
            "$lt": next_month.strftime("%Y-%m-%dT00:00:00.000")
        }
    }, {"_id": False}).to_list(length=None)

    grouped = defaultdict(list)
    for record in records:
        user = users_by_id.get(record["userId"])
        if not user:
            continue

        pay_rate = await mongo.pay_rates_collection.find_one(
            {"id": user.get("payRate", {}).get("id")},
            {"_id": False}
        )

        total_hours = record.get("hours", 0.0)
        total_amount = 0.0

        if pay_rate and pay_rate["payrollScheme"]["key"] == "hourly":
            overtime_threshold = pay_rate.get("overtimeThreshold", 0)
            base_hours = min(total_hours, overtime_threshold)
            overtime_hours = max(total_hours - overtime_threshold, 0)

            base_rate = pay_rate.get("baseRate", 0)
            overtime_rate = pay_rate.get("overtimeRate", base_rate)

            total_amount = round(base_hours * base_rate + overtime_hours * overtime_rate, 2)

        grouped[record["userId"]].append({
            "date": record["date"].split("T")[0],
            "hours": total_hours,
            "amount": total_amount
        })

    result = []
    for user_id, data in grouped.items():
        user = await mongo.users_collection.find_one({"id": user_id}, {"_id": False})
        result.append({
            "user": user,
            "userId": user_id,
            "data": data
        })

    return response({
        "records": result,
        "ok": True
    }, start_time=start_time)


@router.post("/update-record", tags=[""])
async def update_time_tracking_record(params: dict):
    start_time = time()

    user_id = params["userId"]
    new_hours = params["hours"]
    date = params["date"]

    user = await mongo.users_collection.find_one({"id": user_id}, {"_id": False})
    pay_rate = await mongo.pay_rates_collection.find_one(
        {"id": user.get("payRate", {}).get("id")},
        {"_id": False}
    )

    await mongo.time_tracking_collection.update_one(
        {"date": date, "userId": user_id},
        {"$set": {"hours": new_hours}},
        upsert=True
    )

    return response({
        "ok": True
    }, start_time=start_time)
