-- ====================================================================
-- Fix GetProfileSalaryLevel to use calendar arithmetic
-- This changes the years/months/days calculation from fixed formulas
-- to actual calendar arithmetic, matching calculateGovAge behavior
-- ====================================================================

DELIMITER $$

DROP PROCEDURE IF EXISTS `GetProfileSalaryLevel`$$

CREATE DEFINER=`root`@`%` PROCEDURE `GetProfileSalaryLevel`(
    IN personId VARCHAR(36),
    IN _date DATE
)
BEGIN
WITH ordered AS (
    SELECT * FROM profileSalary WHERE profileId = personId AND commandCode IN ('0','1','2','3','4','8','9','10','11','12','13','14','15','16','20')
),
work_session AS (
    SELECT *,
           COALESCE(
               SUM(CASE WHEN commandCode IN (12,15,16) THEN 1 ELSE 0 END)
               OVER (ORDER BY commandDateAffect, commandDateSign
                    ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),
           0) AS sessionId
    FROM ordered
),
session_end AS (
    SELECT sessionId, MAX(commandDateAffect) AS sessionEndDate
    FROM work_session
    GROUP BY sessionId
),
level_change AS (
    SELECT *,
           CASE
               WHEN LAG(positionLevel) OVER (ORDER BY commandDateAffect, commandDateSign) = positionLevel
                AND LAG(positionType) OVER (ORDER BY commandDateAffect, commandDateSign) = positionType
                AND LAG(positionCee) OVER (ORDER BY commandDateAffect, commandDateSign) = positionCee
                AND LAG(sessionId) OVER (ORDER BY commandDateAffect, commandDateSign) = sessionId
               THEN 0
               ELSE 1
           END AS isNewLevel
    FROM work_session
),
level_group AS (
    SELECT *,
           SUM(isNewLevel) OVER (ORDER BY commandDateAffect, commandDateSign) AS levelGroup
    FROM level_change
),
first_rows AS (
    SELECT * FROM (
        SELECT *,
               ROW_NUMBER() OVER (PARTITION BY levelGroup ORDER BY commandDateAffect, commandDateSign) AS rnLevel
        FROM level_group
    ) t WHERE rnLevel = 1
),
rows_with_duration AS (
    SELECT
        fr.*,
        LEAD(fr.sessionId)         OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) AS nextSessionId,
        CASE
            WHEN LEAD(fr.commandDateAffect) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) IS NULL
                THEN NULL
            WHEN LEAD(fr.sessionId) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) <> fr.sessionId
                THEN TIMESTAMPDIFF(DAY, fr.commandDateAffect, se.sessionEndDate) + 1
            ELSE
                TIMESTAMPDIFF(DAY, fr.commandDateAffect,
                    LEAD(fr.commandDateAffect) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign))
        END AS duration_days
    FROM first_rows fr
    LEFT JOIN session_end se ON se.sessionId = fr.sessionId
),
resultWithDiff AS (
    SELECT
        *,
        LAG(duration_days) OVER (ORDER BY commandDateAffect, commandDateSign) AS days_diff
    FROM rows_with_duration
)
SELECT
    r.commandDateAffect,
    r.positionType,
    r.positionLevel,
    r.positionCee,
    r.days_diff,
    CASE
        WHEN LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign) IS NOT NULL THEN
            TIMESTAMPDIFF(YEAR, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect)
        ELSE 0
    END AS Years,
    CASE
        WHEN LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign) IS NOT NULL THEN
            TIMESTAMPDIFF(MONTH, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) % 12
        ELSE 0
    END AS Months,
    CASE
        WHEN LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign) IS NOT NULL THEN
            TIMESTAMPDIFF(DAY,
                DATE_ADD(
                    DATE_ADD(LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign),
                        INTERVAL TIMESTAMPDIFF(YEAR, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) YEAR),
                    INTERVAL TIMESTAMPDIFF(MONTH, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) MONTH),
                r.commandDateAffect) + 1
        ELSE 0
    END AS Days,
    r.posNo,
    r.positionExecutive,
    r.orgRoot,
    r.orgChild1,
    r.orgChild2,
    r.orgChild3,
    r.orgChild4,
    r.commandCode,
    r.commandName,
    r.commandNo,
    r.commandYear,
    r.remark
FROM resultWithDiff r

UNION ALL

SELECT
    _date, NULL, NULL, NULL,
    TIMESTAMPDIFF(DAY, MAX(commandDateAffect), _date) + 1,
    TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date),
    TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12,
    TIMESTAMPDIFF(DAY,
        DATE_ADD(
            DATE_ADD(MAX(commandDateAffect),
                INTERVAL TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date) YEAR),
            INTERVAL TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) MONTH),
        _date) + 1,
    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
    NULL,NULL,NULL,NULL
FROM resultWithDiff;

END$$

DELIMITER ;
