import { isNil } from 'lodash-es';

import {
  type Goal,
  type GoalOwner,
  type GoalPayload,
  GoalProgressTypes,
} from '../../types';
import { normalizeDescription, utcCalendarDayToFormDate } from '../../utils';

function getResponsibleArray(goal?: Goal) {
  if (goal?.goalOwners?.[0]?.ownerUser) {
    return [goal.goalOwners[0].ownerUser];
  }
  return [];
}

export function getDefaultValues(goal: Goal) {
  return {
    title: goal?.title,
    hasDescription: !isNil(goal?.description),
    description: goal?.description,
    valueType: goal?.valueType,
    visibility: goal?.visibility,
    type: goal?.type,
    priority: goal?.priority,
    responsible: getResponsibleArray(goal),
    startDate: goal?.startDate && utcCalendarDayToFormDate(goal.startDate),
    endDate: goal?.endDate && utcCalendarDayToFormDate(goal.endDate),
    goalCycleId: goal?.goalCycleId || 0,
    startingValue: goal?.startingValue,
    objectiveValue: goal?.objectiveValue,
    valueUnit: goal?.valueUnit,
    minValue: goal?.minValue,
    maxValue: goal?.maxValue,
    status: goal?.status,
    formulaChain: goal?.formulaChainId
      ? { value: goal.formulaChainId, label: '' }
      : null,
    goalCycle: {},
  };
}

export function buildGoalPayload(formValues: Goal): GoalPayload {
  const isFormBinary = formValues.valueType === GoalProgressTypes.BINARY;
  const isFormNumber = formValues.valueType === GoalProgressTypes.NUMBER;

  let ownerIds: number[] = [];
  if (Array.isArray(formValues.responsible)) {
    ownerIds = formValues.responsible.flatMap(user =>
      user ? [user.userId ?? user.id] : [],
    );
  } else if (formValues.responsible) {
    ownerIds = [formValues.responsible.userId ?? formValues.responsible.id];
  }

  const basePayload = {
    title: formValues.title,
    description: formValues.hasDescription
      ? (normalizeDescription(formValues.description) ?? null)
      : null,
    valueType: formValues.valueType,
    visibility: formValues.visibility,
    type: formValues.type,
    priority: formValues.priority,
    startDate: formValues.startDate,
    endDate: formValues.endDate,
    goalCycleId: formValues.goalCycleId || 0,
    ownerIds,
  };

  if (isFormBinary) {
    return {
      ...basePayload,
      startingValue: 0,
      objectiveValue: 1,
    };
  }

  return {
    ...basePayload,
    startingValue: parseFloat(formValues.startingValue as string),
    objectiveValue: parseFloat(formValues.objectiveValue as string),
    formulaChainId: formValues.formulaChain?.value || null,
    ...(isFormNumber && { valueUnit: formValues.valueUnit?.trim() || null }),
    ...(formValues.minValue && {
      minValue: parseFloat(formValues.minValue as string),
    }),
    ...(formValues.maxValue && {
      maxValue: parseFloat(formValues.maxValue as string),
    }),
  };
}

export function isGoalFormValid(
  responsible: GoalOwner | GoalOwner[] | undefined,
  isBinary: boolean,
  startingValue: string | number,
  objectiveValue: string | number,
): boolean {
  const hasResponsible = Array.isArray(responsible)
    ? responsible.length > 0
    : !!responsible;
  return hasResponsible && (isBinary || startingValue !== objectiveValue);
}
