import { type User } from 'src/types/user';

export enum GoalProgressTypes {
  PERCENTAGE = 'PERCENTAGE',
  BINARY = 'BINARY',
  NUMBER = 'NUMBER',
  MONETARY = 'MONETARY',
}

export enum GoalTypes {
  INDIVIDUAL = 'INDIVIDUAL',
  DEPARTMENT = 'DEPARTMENT',
  COMPANY = 'COMPANY',
}

export enum GoalVisibilityTypes {
  PUBLIC = 'PUBLIC',
  PRIVATE = 'PRIVATE',
}

export enum GoalPriorityTypes {
  LOW = 'LOW',
  MEDIUM = 'MEDIUM',
  HIGH = 'HIGH',
}

export enum GoalStatus {
  IN_PROGRESS = 'IN_PROGRESS',
  DRAFT = 'DRAFT',
  FINISHED = 'FINISHED',
}

export enum GoalCycleStatus {
  DRAFT = 'DRAFT',
  PENDING = 'PENDING',
  IN_PROGRESS = 'IN_PROGRESS',
  FINISHED = 'FINISHED',
}

export type Category = {
  id: number;
  title: string;
};

export type CategoryOption = Partial<Category> & {
  inputValue?: string;
};

export type GoalOwner = {
  id: number;
  goalId: number;
  userId: number;
  ownerUser: {
    deleted: boolean;
    employeeInternalId: string;
    firstName: string;
    lastName: string;
    profilePicture: string;
    userId: number;
    id: number;
  };
  createdAt: Date;
  updatedAt: Date;
};

export type Goal = {
  id: number;
  instanceId: number;
  title: string;
  description: string;
  type: GoalTypes;
  goalCycleId: number;
  valueType: GoalProgressTypes;
  currentValue: number;
  startingValue: string;
  objectiveValue: string;
  visibility: GoalVisibilityTypes;
  priority: GoalPriorityTypes;
  goalOwners: GoalOwner[];
  progress: number;
  responsibleId: number;
  status: string;
  createdAt: Date;
  startDate: Date;
  endDate: Date;
  updatedAt: Date;
  ownerIds?: number[];
  valueUnit: string;
  minValue: string;
  maxValue: string;
  profilePicture: string;
  weight?: number;
  formulaChainId?: number;
  hasDescription?: boolean;
  responsible?: GoalOwner[] | GoalOwner;
  formulaChain: GoalFormulaChainSelect | null;
  goalCycle?: GoalCycle;
};

export type IndividualGoal = {
  goal: Goal;
  goalId: number;
  weight: number;
};

export const GoalCycleProgressController = {
  ADMIN: 'ADMIN',
  BOSS: 'BOSS',
  OWNER: 'OWNER',
} as const;

export type GoalCycleProgressControllerValue =
  (typeof GoalCycleProgressController)[keyof typeof GoalCycleProgressController];

export type GoalCycle = {
  name: string;
  id: number;
  creatorId: number;
  isForIndividuals: boolean;
  status: GoalCycleStatus;
  startDate: Date;
  endDate: Date;
  createdAt: Date;
  updatedAt: Date;
  formulaChain: GoalFormulaChain | null;
  formulaChainId: number | null;
  goalCount: number | null;
  hasFormulas: boolean;
  enforceGoalCountBounds: boolean;
  minGoalsPerOwner: number | null;
  maxGoalsPerOwner: number | null;
  progressControlConfig: GoalCycleProgressControllerValue[];
};

export enum GoalProgressChange {
  DELTA_VALUE = 'DELTA_VALUE',
  TOTAL_VALUE = 'TOTAL_VALUE',
}

export type GoalProgress = {
  description: string | null;
  type: GoalProgressChange | null;
  value: number | null;
};

export type GoalHistory = {
  createdAt: Date;
  description: string;
  goalId: number;
  id: number;
  type: GoalProgressChange | null;
  updatedAt: Date;
  user: User;
  userId: number;
  value: number | null;
};

export enum GoalErrorCodes {
  INVALID_GOAL_OWNER = 'INVALID_GOAL_OWNER',
  BAD_REQUEST = 'BAD_REQUEST',
  INVALID_GOAL_PUBLISH = 'INVALID_GOAL_PUBLISH',
  INVALID_GOAL_FORMULA_CONFIGURATION = 'INVALID_GOAL_FORMULA_CONFIGURATION',
  CANNOT_PUBLISH_GOAL_INDIVIDUALLY = 'CANNOT_PUBLISH_GOAL_INDIVIDUALLY',
  GOAL_CYCLE_INVALID_GOAL_COUNT_BOUNDS = 'GOAL_CYCLE_INVALID_GOAL_COUNT_BOUNDS',
}

export type GoalTeamUser = {
  avgProgress: number;
  goalCount: number;
  ownerUser: User;
  userId: number;
};

export type GoalCycleStats = {
  subordinatesCount: number;
  subordinatesWithGoals: number;
  subordinatesAssignmentPercentage: number;
};

export type GoalCycleRangeFields = {
  requiredFields: string[];
};

// Goal Formula Types
export enum GoalFormulaChainStatus {
  DRAFT = 'DRAFT',
  IN_USE = 'IN_USE',
}

export type GoalFormulaChain = {
  id?: number;
  title: string;
  goalFormulas: GoalFormula[];
  createdAt?: string;
  updatedAt?: string;
  formulaCount?: number;
  status?: GoalFormulaChainStatus;
};

export type GoalFormulaChainSelect = GoalFormulaChain & {
  label: string;
  value: number;
};

export enum Boundary {
  STARTING_VALUE = 'startingValue',
  MIN_VALUE = 'minValue',
  OBJECTIVE_VALUE = 'objectiveValue',
  MAX_VALUE = 'maxValue',
}

export enum FormulaTrendType {
  INCREASING = 'INCREASING',
  DECREASING = 'DECREASING',
}

export type RangeDefinition = {
  id: number;
  start: { field: Boundary };
  end: { field: Boundary } | null;
};

export type GoalFormulaRange = {
  start: {
    label: string;
    field: Boundary;
  };
  end: {
    label: string;
    field: Boundary;
  } | null;
};

export type GoalFormula = {
  id?: number;
  title: string;
  goalFormulaRange: GoalFormulaRange;
  mathExpression: string | null;
  createdAt?: string;
  updatedAt?: string;
};

export type GoalCyclesConfiguration = {
  goalFlowEnabled: boolean;
  mathFormulasEnabled?: boolean;
  bossCanEditPublishedObjectives?: boolean;
};

export type GoalPayload = {
  title: string;
  description: string | null;
  valueType: GoalProgressTypes;
  visibility: GoalVisibilityTypes;
  type: GoalTypes;
  priority: GoalPriorityTypes;
  startDate: Date;
  endDate: Date;
  goalCycleId: number | string;
  ownerIds: number[];
  startingValue: number;
  objectiveValue: number;
  formulaChainId?: number | null;
  valueUnit?: string | null;
  minValue?: number;
  maxValue?: number;
};
