import axiosInstance from '@/utills/axiosInstance';

// ── Types ────────────────────────────────────────────────────────────────────

export interface ValidatePromotionParams {
  userId: number;
  toRoleId: number;
  toDesignationId?: number;
  // Set when validating a Fill Vacancies sub-promotion: the wizard's
  // top-level employee + their target role, so the backend can tell a
  // CM->GM sub-promotion apart from an orphaned one when the city's first
  // Growth Head is being created by that same primary promotion, in the
  // same not-yet-executed chain.
  primaryPromotionUserId?: number;
  primaryPromotionToRoleId?: number;
}

export interface ValidationVacancy {
  launchId: number;
  launchName: string;
  roleId: number;
  roleName: string;
  type: 'launch_sales' | 'launch_managers';  // slot type — needed to build slotType in execute payload
}

export interface ValidationLead {
  userId: number;
  userName: string;
  launchId: number;
  launchName: string;
  leadCount: number;
}

export interface ValidatePromotionResponse {
  userId: number;
  userName: string;
  currentRoleId: number;
  currentRoleName: string;
  currentDesignationId?: number;
  currentDesignationName?: string;
  toRoleId: number;
  toRoleName: string;
  toDesignationId?: number;
  toDesignationName?: string;
  // 'tree' for TL->CM, CM->GM, GM->GH (may cascade into a multi-level
  // hierarchy vacancy chain); 'standard' for everything else (e.g. FS->TL).
  promotionType?: 'standard' | 'tree';
  needsLaunchAssignment: boolean;
  needsLeadTransfer: boolean;
  canCreateLaunch?: boolean;
  vacancies: ValidationVacancy[];
  currentLaunchIds?: number[];
  leads: ValidationLead[];
  totalBookedLeadCount?: number;
  bookedLeadsByLaunch?: { launchId: number; launchName: string; count: number }[];
  availableLaunches?: { id: number; name: string }[];
  availableManagers?: { id: number; name: string; roleName: string }[];
  // Suggested "Reports To" pick — the employee's current manager's manager,
  // when that person is a valid choice in availableManagers.
  defaultManagerId?: number;
}

export interface PromotionChainEntry {
  userId: number;
  fromRoleId: number;        // required by BE phase-2 chain consistency check
  toRoleId: number;
  toDesignationId?: number;
  targetLaunchIds?: number[]; // renamed from launchIds to match BE field name
  reportsToUserId?: number;
  // Set when this entry is filling a vacated seat (Promote from team / bulk /
  // cascade) — whoever reported to this userId now reports to this entry's user.
  previousHolderUserId?: number;
  // FS -> TL only: explicitly hand-picked field_sales employees who now
  // report to this newly promoted Team Leader, regardless of who they
  // previously reported to.
  teamMemberIds?: number[];
}

export interface ReplacementEntry {
  launchId: number;
  roleId: number;
  userId: number;
  slotType: 'launch_sales' | 'launch_managers';  // required by BE phase-3 branch
  // Manager-role replacements only (slotType === 'launch_managers'): whoever
  // vacated this exact seat — the same person a "Promote from team" filler
  // for this vacancy would get as reportsToUserId/previousHolderUserId. The
  // replacement now reports to them, same as a promoted filler would.
  reportsToUserId?: number;
}

export interface LeadTransferEntry {
  fromUserId: number;
  fromLaunchId: number;
  toUserId?: number;
  toLaunchId?: number;
  // True when toLaunchId is a placeholder id referencing an entry in
  // newCreatedLaunch rather than an existing, already-persisted launch.
  newlyCreateLaunchTransfer?: boolean;
}

export interface NewCreatedLaunchEntry {
  id: number; // placeholder id — matches the toLaunchId it's referenced by
  name: string;
  location?: string;
  cityId: number;
  userId: number; // chain entry whose promoted user becomes this launch's manager
  teamMemberIds?: number[]; // team members to assign to this launch as launch_sales
}

export interface ExecutePromotionPayload {
  effectiveDate: string;
  chain: PromotionChainEntry[];
  replacements: ReplacementEntry[];
  leadTransfers: LeadTransferEntry[];
  newCreatedLaunch: NewCreatedLaunchEntry[];
}

export interface AchievementVerification {
  userId: number;
  launchId: number;
  match: boolean;
  before: Record<string, number>;
  after: Record<string, number>;
}

export interface ExecutePromotionResponse {
  success: boolean;
  message: string;
  achievementVerification?: AchievementVerification[];
  errors?: string[];
}

export interface PromotionHistoryRecord {
  id: number;
  createdAt: string;
  effectiveDate: string;
  employeeName: string;
  fromRoleName: string;
  toRoleName: string;
  status: string;
  executedByName: string;
}

// ── API Functions ────────────────────────────────────────────────────────────

export async function validatePromotion(
  params: ValidatePromotionParams,
): Promise<ValidatePromotionResponse> {
  const response = await axiosInstance.post(
    '/api/v1/hierarchy/promotions/validate',
    params,
  );
  return response.data?.data ?? response.data;
}

export async function executePromotion(
  payload: ExecutePromotionPayload,
): Promise<ExecutePromotionResponse> {
  const response = await axiosInstance.post(
    '/api/v1/hierarchy/promotions',
    payload,
  );
  return response.data?.data ?? response.data;
}

export async function getPromotionHistory(): Promise<PromotionHistoryRecord[]> {
  const response = await axiosInstance.get('/api/v1/hierarchy/promotions');
  const data = response.data?.data ?? response.data;
  return Array.isArray(data) ? data : data?.records ?? [];
}
