import logging

from fastapi import APIRouter, Depends, Request

from intranet.trip.src.exceptions import PermissionDenied
from intranet.trip.src.api.auth import (
    has_person_perm,
    is_holding_coordinator,
)
from intranet.trip.src.api.depends import Pagination, get_unit_of_work
from intranet.trip.src.api.schemas import PaginatedResponse
from intranet.trip.src.api.schemas.employee import Employee
from intranet.trip.src.logic.employees import complement_employees
from intranet.trip.src.models.employee import EmployeeFilter
from intranet.trip.src.unit_of_work import UnitOfWork

logger = logging.getLogger(__name__)
router = APIRouter()


@router.get(
    '/{company_id}/employees',
    status_code=200,
    response_model=PaginatedResponse[Employee],
)
async def employee_list(
    request: Request,
    company_id: int,
    employee_filter: EmployeeFilter = Depends(EmployeeFilter),
    pagination: Pagination = Depends(Pagination),
    uow: UnitOfWork = Depends(get_unit_of_work(read_only=True)),
):
    user = request.state.user
    company = await uow.companies.get_company(company_id)
    if not is_holding_coordinator(user, company.holding_id):
        log_message = 'The user does not have permission to access the list of employees'
        raise PermissionDenied(log_message=log_message)
    pagination.limit = min(pagination.limit, 15)  # limitation count of results in one response
    employees, count = await uow.employees.get_list_and_count(
        company_id=company_id,
        employee_filter=employee_filter,
        limit=pagination.limit,
        offset=pagination.offset,
    )
    employees = await complement_employees(uow, employees, request.state.user)
    return pagination.get_paginated_response(data=employees, count=count)


@router.get(
    '/{company_id}/employees/{employee_id}',
    status_code=200,
    response_model=Employee,
)
async def employee_detail(
    request: Request,
    company_id: int,
    employee_id: int,
    uow: UnitOfWork = Depends(get_unit_of_work(read_only=True)),
):
    user = request.state.user
    person = await uow.persons.get_person(employee_id)
    if not has_person_perm(user, person):
        log_message = 'The user does not have permission to access the details about employee'
        raise PermissionDenied(log_message=log_message)

    employee = await uow.employees.get_employee(company_id, employee_id)
    employees = await complement_employees(uow, [employee], request.state.user)
    return employees[0]


@router.post(
    '/{company_id}/employees/{employee_id}/activate',
    status_code=204,
)
async def employee_activate(
    request: Request,
    company_id: int,
    employee_id: int,
    approver_id: int,
    uow: UnitOfWork = Depends(get_unit_of_work(read_only=True)),
):
    # TODO: activate employee
    return


@router.post(
    '/{company_id}/employees/{employee_id}/reject',
    status_code=204,
)
async def employee_reject(
    request: Request,
    company_id: int,
    employee_id: int,
    uow: UnitOfWork = Depends(get_unit_of_work(read_only=True)),
):
    # TODO: reject employee
    return


@router.post(
    '/{company_id}/employees/{employee_id}/block',
    status_code=204,
)
async def employee_block(
    request: Request,
    company_id: int,
    employee_id: int,
    uow: UnitOfWork = Depends(get_unit_of_work(read_only=True)),
):
    # TODO: block employee
    return


@router.post(
    '/{company_id}/employees/{employee_id}/restore',
    status_code=204,
)
async def employee_restore(
    request: Request,
    company_id: int,
    employee_id: int,
    uow: UnitOfWork = Depends(get_unit_of_work(read_only=True)),
):
    # TODO: restore employee
    return


@router.post(
    '/{company_id}/employees/{employee_id}/grant_coordinator',
    status_code=204,
)
async def employee_grant_coordinator(
    request: Request,
    company_id: int,
    employee_id: int,
    uow: UnitOfWork = Depends(get_unit_of_work(read_only=True)),
):
    # TODO: grant coordinator
    return


@router.post(
    '/{company_id}/employees/{employee_id}/revoke_coordinator',
    status_code=204,
)
async def employee_revoke_coordinator(
    request: Request,
    company_id: int,
    employee_id: int,
    uow: UnitOfWork = Depends(get_unit_of_work(read_only=True)),
):
    # TODO: update employee's details
    return


@router.post(
    '/{company_id}/employees/{employee_id}/change_approver',
    status_code=204,
)
async def employee_change_approver(
    request: Request,
    company_id: int,
    employee_id: int,
    approver_id: int,
    uow: UnitOfWork = Depends(get_unit_of_work()),
):
    # TODO: update approver
    return
