from datetime import datetime

from staff.lib.exceptions import ErrorWithStatusCode
from staff.person.models import Staff, StaffCar

from staff.person_profile.errors import log_does_not_exist_staff_login

import logging
logger = logging.getLogger('person_profile.controllers.cars')


class CarsError(ErrorWithStatusCode):
    pass


def get_cars_initial(login):
    return (
        StaffCar.objects
        .values('id', 'model', 'plate')
        .filter(staff__login=login, intranet_status=1)
        .order_by('position')
    )


def update_cars(login, new_cars_data):
    now = datetime.now()
    with log_does_not_exist_staff_login(logger=logger, message_params=[login], raise_e=CarsError):
        staff_id = Staff.objects.values_list('id', flat=True).get(login=login)

    old_ids = set(
        StaffCar.objects
        .values_list('id', flat=True)
        .filter(staff__login=login, intranet_status=1)
    )

    for position, form_data in enumerate(new_cars_data):
        pk = form_data.get('id')
        car_data = {
            'staff_id': staff_id,
            'modified_at': now,
            'created_at': now,
            'plate': form_data['plate'],
            'model': form_data['model'],
            'position': position,
        }

        if pk is not None:
            car_data['id'] = pk
            old_ids.discard(pk)
        else:
            car_data['created_at'] = now

        try:
            StaffCar(**car_data).save(
                force_insert=not bool(pk),
                force_update=bool(pk)
            )
        except Exception as e:
            logger.exception('Cannot save car data: %s', car_data)
            raise CarsError(e)

    if old_ids:
        for car in StaffCar.objects.filter(id__in=old_ids):
            try:
                car.intranet_status = 0
                car.save()
            except StaffCar.DoesNotExist as e:
                logger.exception('There are no such car: %s', car)
                raise CarsError(e)
