package com.ffii.fpsms.modules.pickOrder.web.models

import com.ffii.fpsms.modules.pickOrder.entity.TruckLaneScheduleLineAction
import jakarta.validation.Valid
import jakarta.validation.constraints.Min
import jakarta.validation.constraints.NotBlank
import jakarta.validation.constraints.NotNull
import jakarta.validation.constraints.Size
import java.time.LocalDateTime
import java.time.LocalTime

data class TruckLaneMoveTargetRequest(
    @field:NotNull
    val truckRowId: Long,
    @field:NotBlank
    @field:Size(max = 100)
    val toTruckLanceCode: String,
    @field:Size(max = 255)
    val toRemark: String? = null,
    @field:NotBlank
    @field:Size(max = 10)
    val toStoreId: String,
    @field:NotNull
    @field:Min(0)
    val toLoadingSequence: Int,
    @field:Size(max = 255)
    val toDistrictReference: String? = null,
)

data class TruckLaneScheduleLineRequest(
    @field:NotNull
    val action: TruckLaneScheduleLineAction,
    val truckRowId: Long? = null,
    @field:NotBlank
    @field:Size(max = 100)
    val toTruckLanceCode: String,
    @field:Size(max = 255)
    val toRemark: String? = null,
    @field:NotBlank
    @field:Size(max = 10)
    val toStoreId: String,
    @field:Min(0)
    val toLoadingSequence: Int? = null,
    @field:Size(max = 255)
    val toDistrictReference: String? = null,
    val shopId: Long? = null,
    @field:Size(max = 50)
    val shopCode: String? = null,
    @field:Size(max = 255)
    val shopName: String? = null,
    val departureTime: LocalTime? = null,
    val logisticId: Long? = null,
)

data class CreateTruckLaneScheduleRequest(
    @field:NotNull
    val executeAt: LocalDateTime,
    @field:Size(max = 500)
    val note: String? = null,
    @field:Valid
    val lines: List<TruckLaneScheduleLineRequest>? = null,
    @field:Valid
    val moves: List<TruckLaneMoveTargetRequest>? = null,
)

data class RetryFailedTruckLaneScheduleRequest(
    val executeAt: LocalDateTime? = null,
)

data class TruckLaneScheduleLineResponse(
    val id: Long,
    val action: String,
    val truckRowId: Long?,
    val shopCode: String?,
    val shopName: String?,
    val fromTruckLanceCode: String?,
    val fromRemark: String?,
    val fromStoreId: String?,
    val toTruckLanceCode: String,
    val toRemark: String?,
    val toStoreId: String,
    val fromLoadingSequence: Int? = null,
    val fromDistrictReference: String? = null,
    val fromDepartureTime: String? = null,
    val toDistrictReference: String? = null,
    val toLoadingSequence: Int? = null,
    val departureTime: String? = null,
    val lineStatus: String,
    val errorMessage: String?,
    val appliedAt: String?,
)

data class SchedulePlanBlockingError(
    val code: String,
    val shopCode: String? = null,
    val shopName: String? = null,
    val truckRowId: Long? = null,
    val messageKey: String,
)

data class TruckLaneScheduleResponse(
    val id: Long,
    val executeAt: String,
    val status: String,
    val source: String,
    val note: String?,
    val appliedAt: String?,
    val errorMessage: String?,
    val snapshotVersionId: Long?,
    val preApplySnapshotVersionId: Long? = null,
    val created: String?,
    val createdBy: String? = null,
    val modifiedBy: String?,
    val lines: List<TruckLaneScheduleLineResponse>? = null,
    val lineCounts: TruckLaneScheduleLineCounts? = null,
)

data class TruckLaneScheduleLineCounts(
    val total: Int,
    val applied: Int,
    val failed: Int,
    val pending: Int,
)

data class PendingTruckRowIdsResponse(
    /** 所有開放排程（PENDING/APPLYING）涉及的 truck rows，供排程驗證、標記用。 */
    val truckRowIds: List<Long>,
    /** 已進入鎖定時間窗（或 APPLYING）的 truck rows，看板不可手改。 */
    val lockedTruckRowIds: List<Long> = emptyList(),
)

data class RouteExcelSchedulePlanPreviewRow(
    val action: String,
    val truckRowId: Long?,
    val shopCode: String?,
    val shopName: String?,
    val toTruckLanceCode: String,
    val toRemark: String?,
    val toStoreId: String,
    val toLoadingSequence: Int?,
)

data class RouteExcelSchedulePlanError(
    val shopCode: String,
    val shopName: String,
    val message: String,
)

data class RouteExcelSchedulePlanResponse(
    val sheetCount: Int,
    val rowCount: Int,
    val lines: List<TruckLaneScheduleLineRequest>,
    val previews: List<RouteExcelSchedulePlanPreviewRow>,
    val errors: List<RouteExcelSchedulePlanError>,
    val blockingErrors: List<SchedulePlanBlockingError> = emptyList(),
    val canCreate: Boolean = true,
    val counts: RouteExcelSchedulePlanCounts,
)

data class RouteExcelSchedulePlanCounts(
    val moves: Int,
    val creates: Int,
    val deletes: Int,
    val ensureLanes: Int,
)

data class ParseTruckLaneScheduleExcelResponse(
    val rowCount: Int,
    val validCount: Int,
    val errorCount: Int,
    val rows: List<TruckLaneScheduleExcelPreviewRow>,
    val errors: List<TruckLaneScheduleExcelRowError>,
)

data class TruckLaneScheduleExcelPreviewRow(
    val rowIndex: Int,
    val shopCode: String,
    val toTruckLanceCode: String,
    val toRemark: String?,
    val toStoreId: String,
    val executeAt: LocalDateTime?,
    val truckRowId: Long?,
)

data class TruckLaneScheduleExcelRowError(
    val rowIndex: Int,
    val message: String,
)

data class ImportTruckLaneScheduleExcelRequest(
    val executeAt: LocalDateTime? = null,
    val note: String? = null,
)
