#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define FILE_PATH "/srv/http/work_orders_debug.json"
#define MAX_NAME 201       // +1 for null terminator
#define MAX_COMMENT 3001

// Unescape basic JSON sequences
void unescape_json_string(char *str) {
    char *src = str, *dst = str;
    while (*src) {
        if (*src == '\\') {
            src++;
            if (*src == '\"') *dst++ = '\"';
            else if (*src == '\\') *dst++ = '\\';
            else if (*src == 'n') *dst++ = '\n';
            else if (*src == 't') *dst++ = '\t';
            else if (*src == 'r') *dst++ = '\r';
            else if (*src == 'b') *dst++ = '\b';
            else if (*src == 'f') *dst++ = '\f';
            else if (*src == 'u') {
                // Skip \uXXXX for now
                src += 4;
            }
            src++;
        } else {
            *dst++ = *src++;
        }
    }
    *dst = '\0';
}

// Extract JSON string value from key (expects "...": "value")
int extract_json_string(char *src, const char *key, char *out, int maxlen) {
    char *key_pos = strstr(src, key);
    if (!key_pos) return 0;

    char *colon = strchr(key_pos, ':');
    if (!colon) return 0;

    char *start = colon + 1;
    while (*start == ' ' || *start == '\t') start++;

    if (*start != '\"') return 0;
    start++; // skip opening quote

    int len = 0, escaped = 0;
    char *p = start;
    while (*p && (escaped || *p != '\"')) {
        if (*p == '\\' && !escaped) {
            escaped = 1;
        } else {
            escaped = 0;
        }
        if (len < maxlen - 1) {
            out[len++] = *p;
        }
        p++;
    }
    out[len] = '\0';
    unescape_json_string(out);
    return 1;
}

// Extract JSON number value
int extract_json_number(char *src, const char *key, char *out, int maxlen) {
    char *start = strstr(src, key);
    if (!start) return 0;
    start = strchr(start, ':');
    if (!start) return 0;
    start++;
    while (*start == ' ' || *start == '\t') start++;
    int len = 0;
    while (*start && *start != ',' && *start != '}' && len < maxlen - 1) {
        out[len++] = *start++;
    }
    out[len] = '\0';
    return 1;
}

// Extract JSON boolean value
int extract_json_bool(char *src, const char *key, int *out) {
    char *start = strstr(src, key);
    if (!start) return 0;
    start = strchr(start, ':');
    if (!start) return 0;
    start++;
    while (*start == ' ' || *start == '\t') start++;
    if (strncmp(start, "true", 4) == 0) {
        *out = 1;
        return 1;
    } else if (strncmp(start, "false", 5) == 0) {
        *out = 0;
        return 1;
    }
    return 0;
}

// Extract media array: returns up to max_items paths in 'paths', sets *total to total count found
int extract_media_list(char *src, const char *key, char paths[][256], int max_items, int *total) {
    *total = 0;
    char *k = strstr(src, key);
    if (!k) return 0;

    char *colon = strchr(k, ':');
    if (!colon) return 0;
    char *p = colon + 1;
    while (*p == ' ' || *p == '\t') p++;

    if (*p != '[') return 0;
    char *lb = p; // left bracket
    // find matching ']'
    int depth = 0;
    while (*p) {
        if (*p == '[') depth++;
        else if (*p == ']') {
            depth--;
            if (depth == 0) break;
        }
        p++;
    }
    if (depth != 0 || *p != ']') return 0;
    char *rb = p; // right bracket

    // scan quoted strings within [ ... ]
    char *q = lb;
    int stored = 0;
    while (q < rb) {
        char *q1 = strchr(q, '\"');
        if (!q1 || q1 >= rb) break;
        char *q2 = strchr(q1 + 1, '\"');
        if (!q2 || q2 > rb) break;
        int len = q2 - (q1 + 1);
        if (len > 0) {
            (*total)++;
            if (stored < max_items) {
                if (len > 255) len = 255;
                strncpy(paths[stored], q1 + 1, len);
                paths[stored][len] = '\0';
                stored++;
            }
        }
        q = q2 + 1;
    }
    return 1;
}

void print_priority(int p) {
    switch (p) {
        case 1:
            printf("<span class='priority-low'>Laag</span>");
            break;
        case 2:
            printf("<span class='priority-medium'>Gemiddeld</span>");
            break;
        case 3:
            printf("<span class='priority-high'>Hoog</span>");
            break;
        default:
            printf("<span class='priority-unknown'>Onbekend</span>");
    }
}

static int is_video_ext(const char *path) {
    // crude check on extension
    const char *dot = strrchr(path, '.');
    if (!dot) return 0;
    char ext[16];
    int i = 0;
    dot++;
    while (*dot && i < 15) {
        ext[i++] = (char)tolower((unsigned char)*dot++);
    }
    ext[i] = '\0';
    return (strcmp(ext, "mp4") == 0 || strcmp(ext, "webm") == 0 || strcmp(ext, "ogg") == 0);
}

static const char* guess_video_mime(const char *path) {
    const char *dot = strrchr(path, '.');
    if (!dot) return "video/mp4";   // safe default
    dot++;
    if (strcasecmp(dot, "mp4") == 0)  return "video/mp4";
    if (strcasecmp(dot, "webm") == 0) return "video/webm";
    if (strcasecmp(dot, "ogg") == 0 || strcasecmp(dot, "ogv") == 0) return "video/ogg";
    return "video/mp4"; // default
}

int main(void) {
    printf("Content-Type: text/html\r\n");
    printf("Cache-Control: no-store, no-cache, must-revalidate\r\n");
    printf("Pragma: no-cache\r\n\r\n");

    printf("<link rel='stylesheet' href='/style.css'>");

    // Wider max-width just for the iframe document
    printf("<style>"
           "@media (min-width:700px){ body{max-width:900px;margin:0 auto;padding:20px;} }"
           "@media (min-width:1120px){ body{max-width:1050px;} }"
           "</style>");

    printf("<script>\n"
    "function notifyHeight(){\n"
    "  try{ parent.postMessage({type:'ordersHeight', h: document.documentElement.scrollHeight}, '*'); }catch(e){}\n"
    "}\n"
    "function toggleField(id){\n"
    "  const full=document.getElementById(id+'-full');\n"
    "  const shortEl=document.getElementById(id+'-short');\n"
    "  const btn=document.getElementById(id+'-btn');\n"
    "  if(full.style.display==='none'){full.style.display='inline';shortEl.style.display='none';btn.innerText='Toon minder';}\n"
    "  else{full.style.display='none';shortEl.style.display='inline';btn.innerText='Toon meer';}\n"
    "  setTimeout(notifyHeight, 50);\n"
    "}\n"
    "function confirmDelete(id){\n"
    "  if(!confirm('Weet je zeker dat je deze order wilt verwijderen?')) return;\n"
    "  fetch('/cgi-bin/delete_order_debug.cgi',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:'id='+encodeURIComponent(id)})\n"
    "  .then(r=>{if(!r.ok) throw new Error('Verwijderen mislukt');location.reload();})\n"
    "  .catch(e=>alert('Fout bij verwijderen: '+e.message));\n"
    "}\n"
    "function toggleBezig(id,state){\n"
    "  fetch('/cgi-bin/toggle_bezig_debug.cgi',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:'id='+encodeURIComponent(id)+'&bezig='+(state?'1':'0')})\n"
    "  .catch(e=>alert('Netwerkfout: '+e.message));\n"
    "}\n"
    "function toggleMedia(id){\n"
    "  const box=document.getElementById('media-'+id);\n"
    "  if(!box) return;\n"
    "  box.style.display=(box.style.display==='none'||box.style.display==='')?'block':'none';\n"
    "  setTimeout(notifyHeight, 50);\n"
    "}\n"
    "// --- Lightbox (no new tabs) ---\n"
    "function openMedia(src, type){\n"
      "if (window.parent && window.parent !== window) {\n"
        "window.parent.postMessage({\n"
          "type: 'openLightbox',\n"
          "src: src,\n"
          "mediaType: type\n"
        "}, '*');\n"
      "}\n"
    "}\n"
    "function closeLightbox(e){\n"
    "  e&&e.preventDefault&&e.preventDefault();\n"
    "  const lb=document.querySelector('.lightbox');\n"
    "  if(!lb) return;\n"
    "  const vid=lb.querySelector('video'); if(vid){ try{vid.pause();}catch(_){} }\n"
    "  lb.parentNode.removeChild(lb);\n"
    "}\n"
    "window.addEventListener('keydown', function(ev){ if(ev.key==='Escape') closeLightbox(ev); });\n"
    "// ---\n"
    "document.addEventListener('error', function(e){\n"
    "  if(e.target && e.target.tagName === 'VIDEO'){\n"
    "    console.warn('Video failed to load, retrying:', e.target.src);\n"
    "    e.target.load();\n"
    "  }\n"
    "}, true);\n"
    "window.addEventListener('load', function(){\n"
    "  notifyHeight();\n"
    "  const media=document.querySelectorAll('img,video');\n"
    "  media.forEach(el=>{\n"
    "    el.addEventListener('loadeddata', ()=>console.log('Video loaded:', el.src));\n"
    "  });\n"
    "  media.forEach(el=>{ el.addEventListener('load', ()=>setTimeout(notifyHeight,50)); });\n"
    "});\n"
    "</script>\n");

    FILE *fp = fopen(FILE_PATH, "r");
    if (!fp) {
        printf("<p>Geen reparaties gevonden.</p>");
        return 1;
    }

    char content[65536];
    size_t len = fread(content, 1, sizeof(content) - 1, fp);
    content[len] = '\0';
    fclose(fp);

    char *entry = content;
    while ((entry = strchr(entry, '{')) != NULL) {
        char *p = entry;
        int depth = 0;
        while (*p) {
            if (*p == '{') depth++;
            else if (*p == '}') depth--;
            if (depth == 0) break;
            p++;
        }
        if (depth != 0) break;

        char *end = p;

        const int BLOCK_SIZE = 8192;
        char block[BLOCK_SIZE];

        int blen = end - entry + 1;
        if (blen >= BLOCK_SIZE) blen = BLOCK_SIZE - 1;
        strncpy(block, entry, blen);
        block[blen] = '\0';

        char id[32] = "", name[MAX_NAME] = "", comment[MAX_COMMENT] = "", priority[32] = "";
        int bezig = 0;   // default false
        int deleted = 0; // default false

        if (!extract_json_number(block, "\"id\"", id, sizeof(id))) {
            printf("<p>Fout: ongeldige ID</p>");
            entry = end + 1;
            continue;
        }

        if (!extract_json_string(block, "\"name\"", name, sizeof(name))) {
            printf("<p>Fout: ongeldige naam bij ID %s</p>", id);
            entry = end + 1;
            continue;
        }

        if (!extract_json_string(block, "\"comment\"", comment, sizeof(comment))) {
            printf("<p>Fout: ongeldige beschrijving bij ID %s</p>", id);
            entry = end + 1;
            continue;
        }

        if (!extract_json_number(block, "\"priority\"", priority, sizeof(priority))) {
            printf("<p>Fout: ongeldige prioriteit bij ID %s</p>", id);
            entry = end + 1;
            continue;
        }

        extract_json_bool(block, "\"bezig\"", &bezig);
        extract_json_bool(block, "\"deleted\"", &deleted);
        if (deleted) { entry = end + 1; continue; }

        // Media list (parse up to 8 to render, count all)
        char media_paths[8][256];
        int media_total = 0;
        int have_media = extract_media_list(block, "\"media\"", media_paths, 8, &media_total);

        printf("<div class='order'>");

        // NAME field with expand/collapse
        int name_len = (int)strlen(name);
        printf("<strong>Naam:</strong> ");
        if (name_len > 70) {
            printf("<span id='%s-name-short'>%.*s...</span>", id, 70, name);
            printf("<span id='%s-name-full' style='display:none;'>%s</span> ", id, name);
            printf("<span class='toggle-btn' onclick='toggleField(\"%s-name\")' id='%s-name-btn'>Toon meer</span><br>", id, id);
        } else {
            printf("%s<br>", name);
        }

        // COMMENT field with expand/collapse
        int comment_len = (int)strlen(comment);
        printf("<strong>Beschrijving:</strong> ");
        if (comment_len > 250) {
            printf("<span id='%s-comment-short'>%.*s...</span>", id, 250, comment);
            printf("<span id='%s-comment-full' style='display:none;'>%s</span> ", id, comment);
            printf("<span class='toggle-btn' onclick='toggleField(\"%s-comment\")' id='%s-comment-btn'>Toon meer</span><br>", id, id);
        } else {
            printf("%s<br>", comment);
        }
        printf("<br>");

        // Priority + controls
        printf("<strong>Prioriteit:</strong> ");
        print_priority(atoi(priority));

        // Action row: left = Bezig + Verwijder, right = Media
        printf("<div style='display:flex; justify-content:space-between; align-items:center; margin-top:6px;'>");

        // Left side: lock items on one line regardless of button display rules
        printf("<div style=\"display:flex; align-items:center; gap:12px; flex-wrap:nowrap;\">");
        printf("<label style='display:flex; align-items:center; gap:6px;'><input type=\"checkbox\" onchange=\"toggleBezig(%s, this.checked)\" %s> Bezig</label>",
               id, bezig ? "checked" : "");
        printf("<button onclick='confirmDelete(\"%s\")'>Verwijder</button>", id);
        printf("</div>");

        // Right side: reserve space and right align the Media button
        printf("<div style='min-width:120px; text-align:right;'>");
        if (have_media && media_total > 0) {
            printf("<button onclick='toggleMedia(%s)'>Media (%d)</button>", id, media_total);
        }
        printf("</div>");

        printf("</div>");

        // Collapsible media strip
        if (have_media && media_total > 0) {
//            printf("<div id='media-%s' style='display:none; margin-top:8px;'>", id);
            printf("<div id='media-%s' class='media-grid' style='display:none;'>", id);

            // render thumbnails/previews for up to 8
            for (int i = 0; i < media_total && i < 8; i++) {
                const char *path = media_paths[i];
                // ensure leading slash for src
                printf(" ");
                if (is_video_ext(path)) {
                    const char *mime = guess_video_mime(path);
                    printf("<div class='media-thumb' onclick='openMedia(\"/%s\",\"video\")'>"
                           "<video muted autoplay loop playsinline preload='auto'>"
                           "<source src='/%s' type='%s'>"
                           "</video>"
                           "<span class='play-badge'>▶</span>"
                           "</div>", path, path, mime);
                } else {
                    printf("<div class='media-thumb' onclick='openMedia(\"/%s\",\"image\")'>"
                        "<img src='/%s' alt='media'>"
                        "</div>", path, path);

                }
            }
            if (media_total > 8) {
                printf("<span style='margin-left:6px; font-size:0.9em; color:#555;'>+%d meer…</span>", media_total - 8);
            }
            printf("</div>");
        }

        printf("</div>");

        entry = end + 1;
    }
    return 0;
}

