-- =============================================================================
-- dc_generate_report  –  Erstellt einen Markdown-Prüfbericht für ein Projekt
--
-- Aufruf:
--   BEGIN dc_generate_report(p_project_id => 1); COMMIT; END;
--   /
--
-- Ergebnis: dc_projects.report_markdown wird mit dem Markdown-Text befüllt.
-- Wird automatisch beim POST /api/dc/projects/:id/complete aufgerufen.
-- Kann manuell via POST /api/dc/projects/:id/report neu generiert werden.
--
-- Aufbau des Berichts:
--   1. Kopf (Projektname, Abschlussdatum)
--   2. Zusammenfassung (OK / Hinweise / Abweichungen)
--   3. Ergebnisse: je Dokument → Kategorie (order_nr) → Frage (order_nr)
--      Icons: ✅ OK  |  ⚠️ Hinweis  |  ❌ Abweichung  |  ❓ Unklar
-- =============================================================================

CREATE OR REPLACE PROCEDURE dc_generate_report(p_project_id IN NUMBER) IS

    v_md       CLOB;
    v_name     dc_projects.name%TYPE;
    v_status   dc_projects.status%TYPE;
    v_done     dc_projects.completed_at%TYPE;

    v_ok_cnt   NUMBER := 0;
    v_warn_cnt NUMBER := 0;
    v_dev_cnt  NUMBER := 0;
    v_unkl_cnt NUMBER := 0;
    v_total    NUMBER := 0;

    -- Emoji-Konstanten via UNISTR (vermeidet Quellcode-Encoding-Probleme)
    C_OK    CONSTANT VARCHAR2(10 CHAR) := UNISTR('\2705');           -- ✅
    C_NOK   CONSTANT VARCHAR2(10 CHAR) := UNISTR('\274C');           -- ❌
    C_WARN  CONSTANT VARCHAR2(10 CHAR) := UNISTR('\26A0\FE0F');      -- ⚠️
    C_UNKL  CONSTANT VARCHAR2(10 CHAR) := UNISTR('\2753');           -- ❓
    C_DOC   CONSTANT VARCHAR2(10 CHAR) := UNISTR('\D83D\DCC4');      -- 📄

    CURSOR c_docs IS
        SELECT d.id, d.filename
        FROM   dc_project_documents d
        WHERE  d.project_id = p_project_id
        ORDER  BY d.uploaded_at, d.id;

    CURSOR c_cats(p_doc_id NUMBER) IS
        SELECT DISTINCT qc.id, qc.name, qc.order_nr
        FROM   dc_question_categories qc
        JOIN   dc_questions           q  ON q.category_id  = qc.id
        JOIN   dc_results             r  ON r.question_id  = q.id
        WHERE  r.project_id = p_project_id
          AND  r.doc_id     = p_doc_id
        ORDER  BY qc.order_nr, qc.name;

    CURSOR c_qs(p_doc_id NUMBER, p_cat_id NUMBER) IS
        SELECT q.question_text,
               r.result_type,
               r.score,
               r.deviation,
               r.warning,
               r.answer,
               r.the_comment
        FROM   dc_questions q
        JOIN   dc_results   r ON r.question_id = q.id
        WHERE  r.project_id  = p_project_id
          AND  r.doc_id      = p_doc_id
          AND  q.category_id = p_cat_id
        ORDER  BY q.order_nr, q.id;

    v_icon VARCHAR2(20 CHAR);

    -- Fügt eine Zeile + Newline an den CLOB an. Akzeptiert CLOB damit kein
    -- implizites CLOB→VARCHAR2-Cast nötig ist (question_text etc. sind CLOBs).
    PROCEDURE ln(p_text IN CLOB DEFAULT NULL) IS
    BEGIN
        IF p_text IS NOT NULL AND DBMS_LOB.GETLENGTH(p_text) > 0 THEN
            DBMS_LOB.APPEND(v_md, p_text);
        END IF;
        DBMS_LOB.APPEND(v_md, TO_CLOB(CHR(10)));
    END ln;

BEGIN
    DBMS_LOB.CREATETEMPORARY(v_md, TRUE);

    SELECT name, status, completed_at
    INTO   v_name, v_status, v_done
    FROM   dc_projects
    WHERE  id = p_project_id;

    SELECT SUM(CASE WHEN deviation   = 1 THEN 1 ELSE 0 END),
           SUM(CASE WHEN warning     = 1 THEN 1 ELSE 0 END),
           SUM(CASE WHEN result_type = 'UNKLAR'
                         AND deviation = 0
                         AND warning   = 0 THEN 1 ELSE 0 END),
           COUNT(*)
    INTO   v_dev_cnt, v_warn_cnt, v_unkl_cnt, v_total
    FROM   dc_results
    WHERE  project_id = p_project_id;

    v_ok_cnt := v_total - v_dev_cnt - v_warn_cnt - v_unkl_cnt;

    -- =========================================================================
    -- Kopf
    -- =========================================================================
    ln('# ' || C_OK || ' Prüfbericht: ' || v_name);
    ln();
    IF v_done IS NOT NULL THEN
        ln('**Abgeschlossen:** ' || TO_CHAR(v_done, 'DD.MM.YYYY HH24:MI'));
    ELSE
        ln('**Erstellt:** ' || TO_CHAR(SYSDATE, 'DD.MM.YYYY HH24:MI'));
    END IF;
    ln();
    ln('---');
    ln();

    -- =========================================================================
    -- Zusammenfassung (keine Tabelle – Plaintext für maximale Kompatibilität)
    -- =========================================================================
    ln('## Zusammenfassung');
    ln();
    ln(C_OK   || '  OK: '           || v_ok_cnt);
    ln(C_WARN || '  Hinweise: '     || v_warn_cnt);
    ln(C_NOK  || '  Abweichungen: ' || v_dev_cnt);
    IF v_unkl_cnt > 0 THEN
        ln(C_UNKL || '  Unklar: '   || v_unkl_cnt);
    END IF;
    ln('**Gesamt: ' || v_total || '**');
    ln();
    ln('---');
    ln();

    -- =========================================================================
    -- Ergebnisse je Dokument → Kategorie (order_nr) → Frage (order_nr)
    -- =========================================================================
    ln('## Ergebnisse');
    ln();

    FOR doc IN c_docs LOOP
        ln('## ' || C_DOC || ' ' || doc.filename);
        ln();

        FOR cat IN c_cats(doc.id) LOOP
            ln();
            ln('### ' || cat.name);
            ln();

            FOR q IN c_qs(doc.id, cat.id) LOOP

                IF    q.deviation   = 1 THEN v_icon := C_NOK;
                ELSIF q.warning     = 1 THEN v_icon := C_WARN;
                ELSIF q.result_type = 'UNKLAR' THEN v_icon := C_UNKL;
                ELSE                            v_icon := C_OK;
                END IF;

                ln();
                ln(v_icon || ' **' || q.question_text || '**');
                ln();

                IF q.answer IS NOT NULL AND DBMS_LOB.GETLENGTH(q.answer) > 0 THEN
                    ln(q.answer);
                    ln();
                END IF;

                IF q.score IS NOT NULL THEN
                    ln('*Score: ' || q.score || '%*');
                END IF;

                IF q.the_comment IS NOT NULL
                   AND DBMS_LOB.GETLENGTH(q.the_comment) > 0 THEN
                    ln();
                    ln('> ' || q.the_comment);
                END IF;

                ln();
            END LOOP;

        END LOOP;

        ln('---');
        ln();
    END LOOP;

    UPDATE dc_projects
    SET    report_markdown = v_md
    WHERE  id = p_project_id;

    DBMS_LOB.FREETEMPORARY(v_md);

EXCEPTION
    WHEN OTHERS THEN
        DBMS_LOB.FREETEMPORARY(v_md);
        RAISE;
END dc_generate_report;
/
