import { OrderItemStatus } from "@prisma/client"
import type { StationProductionWorkflowDto, StationProductionWorkflowStepDto } from "ttm-shared"

export const DEFAULT_PRODUCTION_WORKFLOW_STEPS: StationProductionWorkflowStepDto[] = [
    {
        code: "pending",
        label: "En attente",
        color: "#f59e0b",
        position: 0,
        systemRole: "START",
        active: true,
    },
    {
        code: "preparing",
        label: "En préparation",
        color: "#3b82f6",
        position: 1,
        systemRole: "INTERMEDIATE",
        active: true,
    },
    {
        code: "ready",
        label: "Prêt",
        color: "#10b981",
        position: 2,
        systemRole: "END",
        active: true,
    },
]

export type ProductionStepState = {
    index: number | null
    code: string | null
    label: string | null
    workflowRevision: number | null
}

function normalizeSteps(steps: Array<Partial<StationProductionWorkflowStepDto> & { position: number }> | null | undefined) {
    const activeSteps = (steps ?? [])
        .filter((step) => step.active !== false)
        .sort((a, b) => (a.position ?? 0) - (b.position ?? 0))

    if (activeSteps.length >= 2) {
        return activeSteps.map((step, index) => ({
            id: typeof step.id === "string" ? step.id : undefined,
            code: typeof step.code === "string" ? step.code : `step_${index}`,
            label: typeof step.label === "string" ? step.label : `Étape ${index + 1}`,
            color: typeof step.color === "string" ? step.color : null,
            position: index,
            systemRole: step.systemRole === "START" || step.systemRole === "END" ? step.systemRole : "INTERMEDIATE",
            active: true,
        } satisfies StationProductionWorkflowStepDto))
    }

    return DEFAULT_PRODUCTION_WORKFLOW_STEPS.map((step) => ({ ...step }))
}

export function buildDefaultProductionWorkflowDto(): StationProductionWorkflowDto {
    return {
        enabled: true,
        revision: 1,
        steps: DEFAULT_PRODUCTION_WORKFLOW_STEPS.map((step) => ({ ...step })),
    }
}

export function resolveOperationalProductionWorkflowDto(workflow: StationProductionWorkflowDto | null | undefined): StationProductionWorkflowDto {
    if (workflow?.enabled === false) {
        const fallback = buildDefaultProductionWorkflowDto()
        return {
            ...fallback,
            enabled: false,
            revision: workflow.revision ?? fallback.revision,
        }
    }

    if (!workflow) {
        return buildDefaultProductionWorkflowDto()
    }

    return {
        enabled: workflow.enabled ?? true,
        revision: workflow.revision ?? 1,
        steps: normalizeSteps(workflow.steps),
    }
}

export function toProductionWorkflowDto(station: any): StationProductionWorkflowDto | null {
    if (!station || station.mainType !== "PRODUCTION") return null

    const steps = normalizeSteps(station.productionWorkflowSteps)
    return {
        enabled: station.productionWorkflowEnabled ?? true,
        revision: station.productionWorkflowRevision ?? 1,
        steps,
    }
}

export function buildProductionWorkflowSnapshot(workflow: StationProductionWorkflowDto | null | undefined) {
    return resolveOperationalProductionWorkflowDto(workflow).steps.map((step) => ({
        code: step.code,
        label: step.label,
        color: step.color ?? null,
        position: step.position,
        systemRole: step.systemRole,
        active: step.active,
    }))
}

export function mapProductionStepIndexToStatus(workflow: StationProductionWorkflowDto, index: number | null | undefined): OrderItemStatus {
    if (index == null || index <= 0) return OrderItemStatus.PENDING
    const lastIndex = workflow.steps.length - 1
    if (index >= lastIndex) return OrderItemStatus.READY
    return OrderItemStatus.PREPARING
}

export function getProductionStepState(workflow: StationProductionWorkflowDto, index: number | null | undefined): ProductionStepState {
    if (index == null) {
        return {
            index: null,
            code: null,
            label: null,
            workflowRevision: workflow.revision ?? 1,
        }
    }

    const safeIndex = Math.max(0, Math.min(index, workflow.steps.length - 1))
    const step = workflow.steps[safeIndex] ?? null
    return {
        index: safeIndex,
        code: step?.code ?? null,
        label: step?.label ?? null,
        workflowRevision: workflow.revision ?? 1,
    }
}

export function getStartProductionStepState(workflow: StationProductionWorkflowDto) {
    return getProductionStepState(workflow, 0)
}

export function getReadyProductionStepState(workflow: StationProductionWorkflowDto) {
    return getProductionStepState(workflow, workflow.steps.length - 1)
}

export function getAcknowledgedProductionStepState(workflow: StationProductionWorkflowDto) {
    return getProductionStepState(workflow, Math.min(1, workflow.steps.length - 1))
}

export function getPreviousPreparingProductionStepState(workflow: StationProductionWorkflowDto, currentIndex: number | null | undefined) {
    const lastPreparingIndex = workflow.steps.length > 2 ? workflow.steps.length - 2 : null
    if (lastPreparingIndex == null) return null
    if (currentIndex != null && currentIndex > 0 && currentIndex < workflow.steps.length - 1) {
        return getProductionStepState(workflow, Math.max(1, currentIndex - 1))
    }
    return getProductionStepState(workflow, lastPreparingIndex)
}

export function resolveProductionStepStateForStatus(
    workflow: StationProductionWorkflowDto,
    nextStatus: OrderItemStatus,
    options?: { previousStatus?: OrderItemStatus; previousStepIndex?: number | null }
): ProductionStepState | null {
    switch (nextStatus) {
        case OrderItemStatus.PENDING:
            return getStartProductionStepState(workflow)
        case OrderItemStatus.READY:
            return getReadyProductionStepState(workflow)
        case OrderItemStatus.PREPARING:
            if (workflow.steps.length < 3) return null
            if (options?.previousStatus === OrderItemStatus.READY) {
                return getPreviousPreparingProductionStepState(workflow, options.previousStepIndex)
            }
            if (options?.previousStepIndex != null && options.previousStepIndex > 0 && options.previousStepIndex < workflow.steps.length - 1) {
                return getProductionStepState(workflow, options.previousStepIndex)
            }
            return getAcknowledgedProductionStepState(workflow)
        default:
            return null
    }
}

export function hasProductionStepChanged(previous: ProductionStepState | null | undefined, next: ProductionStepState | null | undefined) {
    return (previous?.index ?? null) !== (next?.index ?? null)
        || (previous?.code ?? null) !== (next?.code ?? null)
        || (previous?.label ?? null) !== (next?.label ?? null)
}

