-- Backfill health-certificate instances from personnel dynamic form data.
-- Status mapping:
-- 1 = missing, 2 = expired, 3 = near expire, 4 = normal

SET @near_expire_days := (
    SELECT CAST(JSON_UNQUOTE(JSON_EXTRACT(bp.`value`, '$.expiryReminderDays')) AS UNSIGNED)
    FROM ftb_param bp
    WHERE bp.`key` = CONCAT('ftbWarningNotice_', MD5('healthCertificate'))
    LIMIT 1
);
SET @near_expire_days := IF(@near_expire_days IS NULL OR @near_expire_days <= 0, 30, @near_expire_days);

INSERT INTO ftb_certificate_instance (
    F_Id,
    F_CertificateType,
    F_TemplateId,
    F_SubjectType,
    F_SubjectId,
    F_CertificateNo,
    F_IssueDate,
    F_ExpireDate,
    F_ExpireTimestamp,
    F_IsLongTerm,
    F_Status,
    F_CertificateImage,
    F_EnabledMark,
    F_CreatorUserId,
    F_CreatorTime,
    F_LastModifyUserId,
    F_LastModifyTime
)
WITH
user_candidates AS (
    SELECT
        TRIM(sr.F_UserId) AS user_id,
        NULLIF(TRIM(sr.F_Phone), '') AS phone,
        1 AS source_priority,
        COALESCE(sr.F_LastModifyTime, sr.F_CreatorTime, '1970-01-01 00:00:00') AS source_time
    FROM ftb_personnels_staff_roster sr
    WHERE sr.F_EnabledMark = 0
      AND sr.F_UserId IS NOT NULL
      AND TRIM(sr.F_UserId) <> ''

    UNION ALL

    SELECT
        TRIM(ea.F_UserId) AS user_id,
        NULLIF(TRIM(ea.F_Phone), '') AS phone,
        2 AS source_priority,
        COALESCE(ea.F_LastModifyTime, ea.F_CreatorTime, '1970-01-01 00:00:00') AS source_time
    FROM ftb_personnels_staff_employment_apply ea
    WHERE ea.F_EnabledMark = 0
      AND ea.F_UserId IS NOT NULL
      AND ea.F_CheckStatus != 5
      AND TRIM(ea.F_UserId) <> ''
),
all_users AS (
    SELECT DISTINCT uc.user_id
    FROM user_candidates uc
),
form_latest AS (
    SELECT
        t.phone,
        t.form_field_id,
        t.form_value
    FROM (
        SELECT
            rfd.F_Phone AS phone,
            rfd.F_FormFieldId AS form_field_id,
            TRIM(rfd.F_Value) AS form_value,
            ROW_NUMBER() OVER (
                PARTITION BY rfd.F_Phone, rfd.F_FormFieldId
                ORDER BY COALESCE(rfd.F_LastModifyTime, rfd.F_CreatorTime) DESC, rfd.F_Id DESC
            ) AS rn
        FROM ftb_personnels_staff_registration_form_data rfd
        WHERE rfd.F_FormFieldId IN ('healthCertificate', 'startHealthDate', 'endHealthDate')
    ) t
    WHERE t.rn = 1
),
candidate_field AS (
    SELECT
        uc.user_id,
        fl.form_field_id,
        fl.form_value,
        CASE
            WHEN fl.form_field_id IN ('startHealthDate', 'endHealthDate') THEN
                CASE
                    WHEN fl.form_value IS NULL OR TRIM(fl.form_value) = '' THEN NULL
                    WHEN fl.form_value REGEXP '^[0-9]{4}[-/][0-9]{2}[-/][0-9]{2}$'
                        THEN STR_TO_DATE(REPLACE(fl.form_value, '/', '-'), '%Y-%m-%d')
                    WHEN fl.form_value REGEXP '^[0-9]{4}[-/][0-9]{2}[-/][0-9]{2}[[:space:]].*$'
                        THEN STR_TO_DATE(REPLACE(SUBSTRING(fl.form_value, 1, 10), '/', '-'), '%Y-%m-%d')
                    ELSE NULL
                END
            ELSE NULL
        END AS parsed_date,
        CASE
            WHEN fl.form_value IS NULL OR TRIM(fl.form_value) = '' THEN 0
            ELSE 1
        END AS has_value,
        uc.source_priority,
        uc.source_time
    FROM user_candidates uc
    LEFT JOIN form_latest fl
        ON fl.phone = uc.phone
),
user_field_best AS (
    SELECT
        t.user_id,
        t.form_field_id,
        t.form_value,
        t.parsed_date
    FROM (
        SELECT
            cf.user_id,
            cf.form_field_id,
            cf.form_value,
            cf.parsed_date,
            ROW_NUMBER() OVER (
                PARTITION BY cf.user_id, cf.form_field_id
                ORDER BY cf.has_value DESC, cf.source_priority ASC, cf.source_time DESC
            ) AS rn
        FROM candidate_field cf
        WHERE cf.form_field_id IS NOT NULL
    ) t
    WHERE t.rn = 1
),
user_field_pivot AS (
    SELECT
        ufb.user_id,
        MAX(CASE WHEN ufb.form_field_id = 'healthCertificate' THEN ufb.form_value END) AS health_certificate,
        MAX(CASE WHEN ufb.form_field_id = 'startHealthDate' THEN ufb.parsed_date END) AS start_health_date,
        MAX(CASE WHEN ufb.form_field_id = 'endHealthDate' THEN ufb.parsed_date END) AS end_health_date
    FROM user_field_best ufb
    GROUP BY ufb.user_id
)
SELECT
    REPLACE(UUID(), '-', '') AS F_Id,
    'healthCertificate' AS F_CertificateType,
    '' AS F_TemplateId,
    1 AS F_SubjectType,
    au.user_id AS F_SubjectId,
    NULL AS F_CertificateNo,
    ufp.start_health_date AS F_IssueDate,
    ufp.end_health_date AS F_ExpireDate,
    case
        when ufp.end_health_date is NULL then 0
        else UNIX_TIMESTAMP(ufp.end_health_date)
    end AS F_ExpireTimestamp,
    0 AS F_IsLongTerm,
    CASE
        WHEN ufp.end_health_date IS NULL THEN 1
        WHEN ufp.end_health_date < CURDATE() THEN 2
        WHEN DATEDIFF(ufp.end_health_date, CURDATE()) <= @near_expire_days THEN 3
        ELSE 4
    END AS F_Status,
    ufp.health_certificate AS F_CertificateImage,
    0 AS F_EnabledMark,
    NULL AS F_CreatorUserId,
    NOW() AS F_CreatorTime,
    NULL AS F_LastModifyUserId,
    NOW() AS F_LastModifyTime
FROM all_users au
LEFT JOIN user_field_pivot ufp
    ON ufp.user_id = au.user_id
ON DUPLICATE KEY UPDATE
    F_IssueDate = VALUES(F_IssueDate),
    F_ExpireDate = VALUES(F_ExpireDate),
    F_IsLongTerm = VALUES(F_IsLongTerm),
    F_Status = VALUES(F_Status),
    F_CertificateImage = VALUES(F_CertificateImage),
    F_EnabledMark = 0,
    F_LastModifyTime = NOW();
