/**
 * TruckLaneMovePlanner — single seam for planning schedule moves from the board UI.
 */
import type {
  CreateTruckLaneScheduleRequest,
  TruckLaneMoveTargetRequest,
} from "@/app/api/shop/actions";
import type {
  ScheduleChangePayload,
  ScheduleLaneOption,
  ScheduleShopRow,
} from "@/components/Shop/ScheduleChangeModal";
import {
  buildCreateScheduleRequest,
  buildCreateScheduleRequestFromModifications,
  buildScheduleLinesFromPlan,
} from "@/components/Shop/scheduleApiAdapter";
import {
  initPlannedLanes,
  listModifications,
  moveShop,
  revertShop,
  type ScheduleDragWorkspaceState,
  type ScheduleModification,
  type ScheduledDeleteSnapshot,
} from "@/components/Shop/scheduleDragWorkspace";
import { buildExecuteAtIso } from "@/components/Shop/scheduleExecuteAt";
import {
  validateScheduleLines,
  type ScheduleLineValidationError,
} from "@/components/Shop/scheduleLineValidation";

export type PlanScheduleSubmitInput = {
  lanes: ScheduleLaneOption[];
  shops: ScheduleShopRow[];
  plannedLanes: ScheduleDragWorkspaceState;
  pendingDeletes: ScheduledDeleteSnapshot[];
  date: string;
  time: string;
  pendingTruckRowIds: Set<number>;
  note?: string | null;
};

export type PlanScheduleSubmitResult =
  | {
      ok: true;
      request: CreateTruckLaneScheduleRequest;
      modifications: ScheduleModification[];
    }
  | { ok: false; errors: ScheduleLineValidationError[] };

export function initPlannerState(
  lanes: ScheduleLaneOption[],
  shops: ScheduleShopRow[],
): ScheduleDragWorkspaceState {
  return initPlannedLanes(lanes, shops);
}

export function planMove(
  state: ScheduleDragWorkspaceState,
  args: Parameters<typeof moveShop>[1],
): ScheduleDragWorkspaceState {
  return moveShop(state, args);
}

export function planRevert(
  state: ScheduleDragWorkspaceState,
  shopId: number,
  currentLaneId: string,
): ScheduleDragWorkspaceState {
  return revertShop(state, shopId, currentLaneId);
}

export function listPlannedModifications(
  state: ScheduleDragWorkspaceState,
): ScheduleModification[] {
  return listModifications(state);
}

export function buildShopCodeByTruckRowId(
  shops: ScheduleShopRow[],
  plannedLanes?: ScheduleDragWorkspaceState,
): Map<number, string> {
  const map = new Map(shops.map((s) => [s.truckRowId, s.shopCode]));
  if (plannedLanes) {
    for (const lane of plannedLanes) {
      for (const shop of lane.shops) {
        if (shop.truckRowId < 0 && shop.shopCode) {
          map.set(shop.truckRowId, shop.shopCode);
        }
      }
    }
  }
  return map;
}

export function validatePlannedSubmit(
  input: PlanScheduleSubmitInput,
): PlanScheduleSubmitResult {
  const executeAt = buildExecuteAtIso(input.date, input.time);
  if (!executeAt) {
    return {
      ok: false,
      errors: [{ truckRowId: 0, messageKey: "schedule_err_execute_at_past" }],
    };
  }
  const modifications = listModifications(input.plannedLanes);
  const lines = buildScheduleLinesFromPlan({
    modifications,
    pendingDeletes: input.pendingDeletes,
    lanes: input.lanes,
    plannedLanes: input.plannedLanes,
  });
  const validation = validateScheduleLines({
    lines,
    lanes: input.lanes,
    plannedLanes: input.plannedLanes,
    pendingTruckRowIds: input.pendingTruckRowIds,
    executeAt,
    shopCodeByTruckRowId: buildShopCodeByTruckRowId(
      input.shops,
      input.plannedLanes,
    ),
  });
  if (!validation.ok) {
    return validation;
  }
  return {
    ok: true,
    modifications,
    request: buildCreateScheduleRequestFromModifications({
      executeAt,
      note: input.note,
      modifications,
      lanes: input.lanes,
      plannedLanes: input.plannedLanes,
      pendingDeletes: input.pendingDeletes,
    }),
  };
}

export function validatePayloadSubmit(input: {
  payload: ScheduleChangePayload;
  lanes: ScheduleLaneOption[];
  shops: ScheduleShopRow[];
  pendingTruckRowIds: Set<number>;
}): { ok: true } | { ok: false; errors: ScheduleLineValidationError[] } {
  const executeAt = buildExecuteAtIso(input.payload.date, input.payload.time);
  if (!executeAt) {
    return {
      ok: false,
      errors: [{ truckRowId: 0, messageKey: "schedule_err_execute_at_past" }],
    };
  }
  const lines = buildScheduleLinesFromPlan({
    modifications: listModifications(input.payload.plannedLanes),
    pendingDeletes: input.payload.pendingDeletes,
    lanes: input.lanes,
    plannedLanes: input.payload.plannedLanes,
  });
  return validateScheduleLines({
    lines,
    lanes: input.lanes,
    plannedLanes: input.payload.plannedLanes,
    pendingTruckRowIds: input.pendingTruckRowIds,
    executeAt,
    shopCodeByTruckRowId: buildShopCodeByTruckRowId(
      input.shops,
      input.payload.plannedLanes,
    ),
  });
}

export function buildRequestFromPayload(
  payload: ScheduleChangePayload,
  lanes: ScheduleLaneOption[],
): CreateTruckLaneScheduleRequest | null {
  const executeAt = buildExecuteAtIso(payload.date, payload.time);
  if (!executeAt) return null;
  return buildCreateScheduleRequest({
    executeAt,
    mappings: payload.mappings,
    lanes,
    plannedLanes: payload.plannedLanes,
    pendingDeletes: payload.pendingDeletes,
    modifications: listModifications(payload.plannedLanes),
  });
}

export type { TruckLaneMoveTargetRequest, ScheduleModification };
