'use server';

import { revalidatePath } from 'next/cache';

import { enhanceAction } from '@kit/next/actions';
import { getLogger } from '@kit/shared/logger';

import {
  NotificationAction,
  createNotificationLog,
} from '../../../../../../../lib/services/audit/notificationEntries.service';
import {
  DoctorAnalysisFeedbackTable,
  DoctorJobSelect,
  DoctorJobUnselect,
  doctorAnalysisFeedbackSchema,
  doctorJobSelectSchema,
  doctorJobUnselectSchema,
} from '../schema/doctor-analysis.schema';
import { ErrorReason } from '../schema/error.type';
import {
  selectJob,
  submitFeedback,
  unselectJob,
} from '../services/doctor-analysis.service';
import { doctorAction } from '../utils/doctor-action';

/**
 * @name selectJobAction
 * @description Creates a feedback item that ties doctor to the job and enables giving feedback.
 */
export const selectJobAction = doctorAction(
  enhanceAction(
    async ({ analysisOrderId, userId }: DoctorJobSelect) => {
      const logger = await getLogger();

      try {
        logger.info({ analysisOrderId }, `Selecting new job`);

        await selectJob(analysisOrderId, userId);
        logger.info({ analysisOrderId }, `Successfully selected`);

        revalidateDoctorAnalysis();
        return { success: true };
      } catch (e) {
        logger.error('Failed to select job', e);
        if (e instanceof Error) {
          revalidateDoctorAnalysis();
          return {
            success: false,
            reason:
              e['message'] === ErrorReason.JOB_ASSIGNED
                ? ErrorReason.JOB_ASSIGNED
                : ErrorReason.UNKNOWN,
          };
        }
        return { success: false, reason: ErrorReason.UNKNOWN };
      }
    },
    {
      schema: doctorJobSelectSchema,
    },
  ),
);

/**
 * @name unselectJobAction
 * @description Removes the current user from a feedback item.
 */
export const unselectJobAction = doctorAction(
  enhanceAction(
    async ({ analysisOrderId }: DoctorJobUnselect) => {
      const logger = await getLogger();
      try {
        logger.info({ analysisOrderId }, `Removing doctor from job`);

        await unselectJob(analysisOrderId);

        logger.info(
          { analysisOrderId },
          `Successfully removed current doctor from job`,
        );
        revalidateDoctorAnalysis();
        return { success: true };
      } catch (e) {
        logger.error('Failed to unselect job', e);
        return { success: false, reason: ErrorReason.UNKNOWN };
      }
    },
    {
      schema: doctorJobUnselectSchema,
    },
  ),
);

/**
 * @name giveFeedbackAction
 * @description Creates or updates doctor analysis feedback.
 */
export const giveFeedbackAction = doctorAction(
  enhanceAction(
    async ({
      feedbackValue,
      userId,
      analysisOrderId,
      status,
    }: {
      feedbackValue: string;
      userId: DoctorAnalysisFeedbackTable['user_id'];
      analysisOrderId: DoctorAnalysisFeedbackTable['analysis_order_id'];
      status: DoctorAnalysisFeedbackTable['status'];
    }) => {
      const logger = await getLogger();
      const isCompleted = status === 'COMPLETED';

      try {
        logger.info(
          { analysisOrderId },
          `Submitting feedback for analysis order...`,
        );

        await submitFeedback(analysisOrderId, userId, feedbackValue, status);
        logger.info({ analysisOrderId }, `Successfully submitted feedback`);

        revalidateDoctorAnalysis();

        if (isCompleted) {
          await createNotificationLog({
            action: NotificationAction.PATIENT_DOCTOR_FEEDBACK_RECEIVED,
            status: 'SUCCESS',
            relatedRecordId: analysisOrderId,
          });
        }

        return { success: true };
      } catch (e: any) {
        if (isCompleted) {
          await createNotificationLog({
            action: NotificationAction.PATIENT_DOCTOR_FEEDBACK_RECEIVED,
            status: 'FAIL',
            comment: e?.message,
            relatedRecordId: analysisOrderId,
          });
        }
        logger.error('Failed to give feedback', e);
        return { success: false, reason: ErrorReason.UNKNOWN };
      }
    },
    {
      schema: doctorAnalysisFeedbackSchema,
    },
  ),
);

function revalidateDoctorAnalysis() {
  revalidatePath('/doctor/analysis');
}
