import { Op } from 'sequelize';
import { TERMINATION_STAGES } from '../config/constants.js';

const norm = (s: string | undefined | null) =>
    String(s || '')
        .toLowerCase()
        .replace(/\s+/g, ' ')
        .trim();

export const isScnResponseJointTargetStage = (targetStage: string | undefined | null): boolean => {
    const n = norm(targetStage);
    if (!n) return false;
    if (n === norm(TERMINATION_STAGES.PERSONAL_HEARING)) return true;
    if (n.includes('evaluation') && n.includes('scn') && n.includes('response')) return true;
    if (n.includes('personal hearing')) return true;
    return false;
};

export const isRbmJointTargetStage = (targetStage: string | undefined | null): boolean => {
    const n = norm(targetStage);
    return n.includes('rbm') && (n.includes('dd-zm') || n.includes('dd zm'));
};

function isSendBackOrReconsiderTimelineAction(action: string | undefined | null): boolean {
    const a = norm(action);
    return (
        a.includes('sent back') ||
        a.includes('send back') ||
        a.includes('reconsider') ||
        a.includes('reconsideration')
    );
}

export type JointRoundTimelineMode = 'scn_response_eval' | 'rbm_review';

/**
 * When a case is sent back / reconsidered to a joint stage, earlier PARTIAL_APPROVE rows must be ignored.
 * Uses workflow timeline entries (written on transition) — newest matching event wins.
 */
export function getJointRoundCutoffMsFromTimeline(
    timeline: unknown,
    mode: JointRoundTimelineMode
): number | null {
    if (!Array.isArray(timeline) || timeline.length === 0) return null;
    const matcher = mode === 'scn_response_eval' ? isScnResponseJointTargetStage : isRbmJointTargetStage;
    const arr = timeline as any[];
    for (let i = arr.length - 1; i >= 0; i--) {
        const e = arr[i];
        if (!isSendBackOrReconsiderTimelineAction(e?.action)) continue;
        if (!matcher(e?.targetStage)) continue;
        const t = e?.timestamp != null ? new Date(e.timestamp).getTime() : NaN;
        if (!Number.isNaN(t)) return t;
    }
    return null;
}

/** Only audit rows created at/after send-back / reconsider to this joint stage count for the current round. */
export function buildJointRoundCreatedAtFilter(cutoffMs: number | null): { createdAt?: { [Op.gte]: Date } } {
    if (cutoffMs == null) return {};
    return { createdAt: { [Op.gte]: new Date(cutoffMs) } };
}
