import { Router } from 'express';
import { AppContainer } from '../container';
import { employeeAuth } from '../middleware/employeeAuth';
import { asyncHandler } from './http';

export function registerTeamShiftRoutes(router: Router, c: AppContainer): void {
  router.post(
    '/teams/:teamId/shift-planner/delegate',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(
        await c.teamShiftFacade.delegate(
          req.params.teamId,
          req.employeeId!,
          req.body.employeeId,
          req.body.effectiveMonth,
        ),
      );
    }),
  );

  router.get(
    '/teams/:teamId/shifts/:month',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(
        (await c.teamShiftFacade.getSchedule(req.params.teamId, req.params.month, req.employeeId!)) ?? {},
      );
    }),
  );

  router.put(
    '/teams/:teamId/shifts/:month',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(
        await c.teamShiftFacade.saveDraft(req.params.teamId, req.params.month, req.employeeId!, req.body),
      );
    }),
  );

  router.post(
    '/teams/:teamId/shifts/:month/generate-draft',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(
        await c.teamShiftFacade.generateAndSaveDraft(
          req.params.teamId,
          req.params.month,
          req.employeeId!,
          req.body,
        ),
      );
    }),
  );

  router.get(
    '/teams/:teamId/shifts/:month/timing-managers',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(
        await c.teamShiftFacade.getTimingManagerAssignments(
          req.params.teamId,
          req.params.month,
          req.employeeId!,
        ),
      );
    }),
  );

  router.put(
    '/teams/:teamId/shifts/:month/timing-managers',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(
        await c.teamShiftFacade.saveTimingManagerAssignments(
          req.params.teamId,
          req.params.month,
          req.employeeId!,
          Array.isArray(req.body?.assignments) ? req.body.assignments : [],
        ),
      );
    }),
  );

  router.get(
    '/teams/:teamId/shift-definitions',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(await c.teamShiftFacade.listShiftDefinitions(req.params.teamId));
    }),
  );

  router.post(
    '/teams/:teamId/shift-definitions',
    employeeAuth,
    asyncHandler(async (req, res) => {
      await c.teamShiftFacade.assertCanManageDefinitions(req.params.teamId, req.employeeId!);
      res.json(
        await c.teamShiftFacade.upsertShiftDefinition(req.params.teamId, req.employeeId!, {
          id: req.body.id,
          name: String(req.body.name || ''),
          startTime: String(req.body.startTime || ''),
          endTime: String(req.body.endTime || ''),
          graceMinutes: req.body.graceMinutes != null ? Number(req.body.graceMinutes) : 10,
          workingDays: Array.isArray(req.body.workingDays) ? req.body.workingDays.map(Number) : undefined,
        }),
      );
    }),
  );

  router.delete(
    '/teams/:teamId/shift-definitions/:definitionId',
    employeeAuth,
    asyncHandler(async (req, res) => {
      await c.teamShiftFacade.assertCanManageDefinitions(req.params.teamId, req.employeeId!);
      res.json(await c.teamShiftFacade.deleteShiftDefinition(req.params.teamId, req.params.definitionId));
    }),
  );

  router.post(
    '/teams/:teamId/shifts/:month/apply-mapped',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(
        await c.teamShiftFacade.applyMappedShiftDefinitions(
          req.params.teamId,
          req.params.month,
          req.employeeId!,
        ),
      );
    }),
  );

  router.post(
    '/teams/:teamId/shifts/:month/submit',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(await c.teamShiftFacade.submit(req.params.teamId, req.params.month, req.employeeId!));
    }),
  );

  router.post(
    '/teams/:teamId/shifts/:month/approve',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(await c.teamShiftFacade.approve(req.params.teamId, req.params.month, req.employeeId!));
    }),
  );

  router.post(
    '/teams/:teamId/shifts/:month/reject',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(
        await c.teamShiftFacade.reject(req.params.teamId, req.params.month, req.employeeId!, req.body.comment),
      );
    }),
  );

  router.get(
    '/employee/shift-teams',
    employeeAuth,
    asyncHandler(async (req, res) => {
      res.json(await c.teamShiftFacade.listShiftTeamsForEmployee(req.employeeId!, req.query.month as string));
    }),
  );
}
