import { Request, Response } from 'express';

import * as targetsService from '@/modules/targets/targets.service';
import catchAsync from '@/shared/utils/catchAsync';
import responseCodes from '@/shared/utils/responseCode/responseCode';
import { pick } from '@/shared/utils';
import { ApiError } from '@/shared/utils/errors';
import { defaultStatus } from '@/shared/utils/responseCode/httpStatusAlias';
import { assertUserCanAccessTeamById } from '@/modules/teams/teams.access';

const { TargetsResponseCodes } = responseCodes;

export const createTargets = catchAsync(
  async (req: Request, res: Response) => {
    const targets = await targetsService.createTargets(
      req.body,
    );
    res.success(
      targets,
      TargetsResponseCodes.SUCCESS,
      'Targets Created Successfully',
    );
  },
);

export const updateTargets = catchAsync(
  async (req: Request, res: Response) => {
    const { id } = pick(req.params, ['id']);

    const updatedTargets = await targetsService.updateTargets(
      id,
      req.body,
    );
    res.success(
      updatedTargets,
      TargetsResponseCodes.SUCCESS,
      'Targets Updated Successfully',
    );
  },
);

export const deleteTargetsById = catchAsync(
  async (req: Request, res: Response) => {
    const { id } = pick(req.params, ['id']);

    const targets = await targetsService.deleteTargets(id);
    res.success(
      targets,
      TargetsResponseCodes.SUCCESS,
      'Targets Deleted Successfully',
    );
  },
);

export const getTargetsById = catchAsync(
  async (req: Request, res: Response) => {
    const { id } = pick(req.params, ['id']);

    const targets = await targetsService.getTargetsById(id);

    res.success(
      targets,
      TargetsResponseCodes.SUCCESS,
      'Targets Fetched Successfully',
    );
  },
);

export const getTargetss = catchAsync(
  async (req: Request, res: Response) => {
    const filter = pick(req.query, ['companyId', 'search']);
    const options = pick(req.query, [
      'sortBy',
      'limit',
      'page',
      'populate',
      'includeTimeStamps',
    ]);

    const targets = await targetsService.queryTargets(
      filter,
      options,
    );

    res.success(
      targets,
      TargetsResponseCodes.SUCCESS,
      'Targets Fetched Successfully',
    );
  },
);

export const getTargetSummary = catchAsync(async (req: Request, res: Response) => {
  const memberId = req.user?.id;
  const { company } = req.user;
  const companyId = company?.id;
  const { month, year, type, teamId } = req.query;

  if (!month || !year) 
    throw new ApiError(
      defaultStatus.BAD_REQUEST,
      'companyId, month and year are required',
      true,
      '',
      TargetsResponseCodes.PAYMENTPLAN_ERROR,
    );

  if (
    String(type) === 'team' &&
    teamId &&
    req.user
  ) {
    await assertUserCanAccessTeamById(req.user, String(teamId));
  }

  const summary = await targetsService.getTargetSummary({
    memberId,
    companyId: companyId.toString(),
    month: Number(month),
    year: Number(year),
    type: type as string,
    teamId: teamId as string,
  });

  res.success(
    summary,
    TargetsResponseCodes.SUCCESS,
    'Target Summary fetched successfully',
  );
});
