/**
 * @fileoverview photo-sheet-ui.js
 * Spezialisiertes Modul für Foto-Dokumentation und OCR-Validierung.
 */

import { mylog } from "./utilities.js";
import { ScCloseButton } from './close-button.js';

export class PhotoSheetUI {
    static instance = null;

    static getInstance() {
        if (!this.instance) this.instance = new PhotoSheetUI();
        return this.instance;
    }

    constructor() {
        if (PhotoSheetUI.instance) return PhotoSheetUI.instance;

        this._isVisible = false;
        this._isCameraAppActive = false;
        this.saveCallback = null;
        this._selectedFile = null;
        this.currentPoi = null;

        this._injectCSS();
        this._injectHTML();
        this._setupGlobalListeners();

        PhotoSheetUI.instance = this;
    }

    _injectHTML() {
        // Der Titel bleibt im Template leer, da er via JS gesetzt wird
        this._cameraTemplate = `
            <div id="photo-content-area">
                <input type="file" id="poi-photo-capture" accept="image/jpeg" capture="environment" style="visibility: hidden; position: absolute;">
                <div id="photo-preview-area">
                    <div id="photo-placeholder">
                        <span style="font-size: 2.5rem;">📷</span><br>
                        Tippen, um Foto zu machen
                    </div>
                    <img id="photo-preview-img" style="display:none">
                </div>

                <div class="photo-input-group">
                    <label for="photo-description-input">Beschreibung (optional)</label>
                    <textarea id="photo-description-input" placeholder="Besonderheiten beim Putzen?" rows="3"></textarea>
                </div>

                <div class="photo-button-row">
                    <button id="photo-skip-btn" class="sc-btn-secondary">Abbrechen</button>
                    <button id="photo-save-btn" class="sc-btn-primary disabled" disabled>Speichern</button>
                </div>
            </div>`;

        const container = document.createElement('div');
        container.id = 'photo-input-container';
        container.className = 'hidden';
        container.innerHTML = `
            <div id="photo-input-header">
                <div class="photo-modal-title"></div>
                <div id="photo-close-button-wrapper"></div>
            </div>
            <div id="photo-main-body"></div>
        `;
        document.body.appendChild(container);

        this.closeButtonComponent = new ScCloseButton('photo-modal-close');
        document.getElementById('photo-close-button-wrapper').appendChild(this.closeButtonComponent.getElement());
    }

    _injectCSS() {
        const css = `
            .photo-modal-backdrop {
                position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
                background: rgba(0, 0, 0, 0.6); z-index: 11001; backdrop-filter: blur(4px);
            }
            #photo-input-container {
                position: fixed; top: 20px; left: 50%; transform: translateX(-50%);
                width: 95%; max-width: 450px; height: calc(100vh - 40px);
                background-color: #fcfcfc; border-radius: 24px;
                box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4); z-index: 11002;
                display: flex; flex-direction: column; overflow: hidden;
            }
            #photo-input-header {
                padding: 18px 24px; background: #fff; border-bottom: 1px solid #eee;
                position: relative; display: flex; align-items: center;
            }
            .photo-modal-title { font-weight: 800; color: #222; font-size: 1.1rem; flex-grow: 1; }
            #photo-close-button-wrapper { position: absolute; right: 15px; top: 50%; transform: translateY(-50%); }
            #photo-main-body { flex-grow: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; }
            #photo-content-area { padding: 20px; }
            #photo-preview-area {
                width: 100%; min-height: 150px; border-radius: 16px;
                border: 2px solid #eee; /* Grüner Rahmen entfernt */
                display: flex; flex-direction: column;
                align-items: center; justify-content: center; gap: 10px;
                cursor: pointer; background: #f9f9f9; padding: 20px;
                box-sizing: border-box; color: #555; font-size: 0.95rem; text-align: center;
            }
            #photo-preview-img { width: 100%; max-height: 250px; object-fit: contain; border-radius: 12px; display: block; }
            .photo-input-group { margin: 20px 0; }
            #photo-description-input {
                width: 100%; padding: 12px; border: 2px solid #eee; border-radius: 12px;
                font-size: 16px !important; outline: none; background: #fff; box-sizing: border-box;
            }
            .photo-button-row { display: flex; gap: 10px; margin-top: 10px; padding-bottom: 20px; }
            .photo-button-row button {
                flex: 1; padding: 15px 5px; border-radius: 50px; font-weight: bold;
                cursor: pointer; border: none; font-size: 0.95rem; transition: all 0.2s;
            }
            .sc-btn-primary { background: #28a745; color: #fff; }
            .sc-btn-primary.disabled { background: #ccc; cursor: not-allowed; opacity: 0.6; }
            .sc-btn-secondary { background: #eee; color: #444; border: 1px solid #ddd !important; }
            .hidden { display: none !important; }
            .photo-spinner-overlay {
                position: absolute; top: 0; left: 0; width: 100%; height: 100%;
                background: rgba(255,255,255,0.8); z-index: 10;
                display: flex; flex-direction: column; align-items: center; justify-content: center;
            }
            .photo-spinner {
                width: 40px; height: 40px; border: 4px solid #f3f3f3;
                border-top: 4px solid #28a745; border-radius: 50%;
                animation: spin 1s linear infinite;
            }
            @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
        `;
        const style = document.createElement('style');
        style.textContent = css;
        document.head.appendChild(style);
    }

    _setupGlobalListeners() {
        this.closeButtonComponent.onClick(() => this.close());
        window.addEventListener('focus', () => {
            if (this._isCameraAppActive) {
                setTimeout(() => { this._isCameraAppActive = false; }, 2000);
            }
        }, { capture: true });
    }

    _bindUIEvents() {
        const previewArea = document.getElementById('photo-preview-area');
        const fileInput = document.getElementById('poi-photo-capture');
        const saveBtn = document.getElementById('photo-save-btn');
        const skipBtn = document.getElementById('photo-skip-btn');

        if (previewArea) {
            previewArea.onclick = () => {
                this._isCameraAppActive = true;
                fileInput.click();
            };
        }
        if (fileInput) fileInput.onchange = (e) => this._handleFileSelection(e);
        if (saveBtn) {
            saveBtn.onclick = () => {
                if (this._selectedFile && this.saveCallback) {
                    this.saveCallback({
                        file: this._selectedFile,
                        description: document.getElementById('photo-description-input').value
                    });
                    this.close();
                }
            };
        }
        if (skipBtn) skipBtn.onclick = () => this.close();
    }

    async _handleFileSelection(e) {
        this._isCameraAppActive = false;
        const file = e.target.files[0];
        if (!file) return;

        const analysis = await this._analyzeStolpersteinOCR(file);
        if (!analysis.isValid) {
            this._resetPreview();
            return;
        }

        this._selectedFile = await this._getResizedBlob(file, 1600, 0.7);
        this._updatePreview(file);
    }

    _updatePreview(file) {
        const img = document.getElementById('photo-preview-img');
        const placeholder = document.getElementById('photo-placeholder');
        const saveBtn = document.getElementById('photo-save-btn');

        if (img.src.startsWith('blob:')) URL.revokeObjectURL(img.src);
        img.src = URL.createObjectURL(file);
        img.style.display = 'block';
        placeholder.style.display = 'none';

        saveBtn.classList.remove('disabled');
        saveBtn.disabled = false;
    }

    _resetPreview() {
        this._selectedFile = null;
        const input = document.getElementById('poi-photo-capture');
        if (input) input.value = '';
        const img = document.getElementById('photo-preview-img');
        if (img) img.style.display = 'none';
        const ph = document.getElementById('photo-placeholder');
        if (ph) ph.style.display = 'block';
        const saveBtn = document.getElementById('photo-save-btn');
        if (saveBtn) {
            saveBtn.classList.add('disabled');
            saveBtn.disabled = true;
        }
    }

    open(poiData, onSave) {
        this.currentPoi = poiData;
        this.saveCallback = onSave;
        this._isVisible = true;

        const container = document.getElementById('photo-input-container');
        const body = document.getElementById('photo-main-body');
        const titleEl = container.querySelector('.photo-modal-title');

        if (body) body.innerHTML = this._cameraTemplate;
        if (titleEl) titleEl.textContent = "Zustand dokumentieren";

        container.classList.remove('hidden');
        this._resetUI();
        this._bindUIEvents();

        if (!document.querySelector('.photo-modal-backdrop')) {
            const backdrop = document.createElement('div');
            backdrop.className = 'photo-modal-backdrop';
            backdrop.onclick = () => this.close();
            document.body.appendChild(backdrop);
        }
        document.body.style.overflow = 'hidden';
    }

    openEmpty(poiData, title) {
        this.currentPoi = poiData;
        this._isVisible = true;

        const container = document.getElementById('photo-input-container');
        const body = document.getElementById('photo-main-body');
        const titleEl = container.querySelector('.photo-modal-title');

        container.classList.remove('hidden');
        if (titleEl) titleEl.textContent = title || "Galerie";
        if (body) body.innerHTML = '<div id="photo-content-area"></div>';

        if (!document.querySelector('.photo-modal-backdrop')) {
            const backdrop = document.createElement('div');
            backdrop.className = 'photo-modal-backdrop';
            backdrop.onclick = () => this.close();
            document.body.appendChild(backdrop);
        }
        document.body.style.overflow = 'hidden';
    }

    close() {
        this._isVisible = false;
        this._selectedFile = null;
        document.getElementById('photo-input-container').classList.add('hidden');
        document.querySelector('.photo-modal-backdrop')?.remove();
        document.body.style.overflow = '';
    }

    _resetUI() {
        const descInput = document.getElementById('photo-description-input');
        if (descInput) descInput.value = '';
        this._resetPreview();
    }

    async _getResizedBlob(imgFile, maxSize = 800, quality = 0.4) {
        return new Promise((resolve) => {
            const reader = new FileReader();
            reader.onload = (e) => {
                const img = new Image();
                img.onload = () => {
                    const canvas = document.createElement('canvas');
                    let w = img.width, h = img.height;
                    if (w > h && w > maxSize) { h *= maxSize / w; w = maxSize; }
                    else if (h > maxSize) { w *= maxSize / h; h = maxSize; }
                    canvas.width = w; canvas.height = h;
                    const ctx = canvas.getContext('2d');
                    ctx.drawImage(img, 0, 0, w, h);
                    canvas.toBlob((blob) => resolve(blob), 'image/jpeg', quality);
                };
                img.src = e.target.result;
            };
            reader.readAsDataURL(imgFile);
        });
    }

    async _analyzeStolpersteinOCR(file) {
        const contentArea = document.getElementById('photo-main-body');
        const spinner = document.createElement('div');
        spinner.className = 'photo-spinner-overlay';
        spinner.innerHTML = `<div class="photo-spinner"></div><p style="margin-top:10px; font-size:0.8rem; font-weight:bold;">Prüfung läuft...</p>`;
        contentArea.appendChild(spinner);

        const controller = new AbortController();
        const timeoutId = setTimeout(() => controller.abort(), 15000); 

        const cleanup = () => {
            clearTimeout(timeoutId);
            if (spinner && spinner.parentNode) spinner.remove();
        };

        try {
            const blob = await this._getResizedBlob(file, 800, 0.4);
            const formData = new FormData();
            formData.append('photo', blob, 'analysis.jpg');

            const response = await fetch(`execute_OCR.php${window.location.search}`, { 
                method: 'POST', 
                body: formData,
                signal: controller.signal 
            });
            
            const data = await response.json();
            if (data.OCRExitCode !== 1) throw new Error(data.ErrorMessage || "Name nicht erkannt(OCR)!");

            const text = data.ParsedResults[0].ParsedText || "";
            const identity = this._validateStoneIdentity(text);

            cleanup();
            if (!identity.isMatch) {
                alert(`❌ Name nicht erkannt!`);
                return { isValid: false };
            }
            return { isValid: true };
        } catch (err) {
            cleanup();
            alert("Fehler: " + err.message);
            return { isValid: false };
        }
    }

    _validateStoneIdentity(ocrText) {
        const cleanText = ocrText.toLowerCase();
        const firstName = (this.currentPoi?.first_name || "").toLowerCase().trim();
        const lastName  = (this.currentPoi?.last_name  || "").toLowerCase().trim();
        const yob       = String(this.currentPoi?.year_of_birth ?? "").trim();
        const hasFirstName = firstName !== "" && cleanText.includes(firstName);
        const hasLastName  = lastName  !== "" && cleanText.includes(lastName);
        const hasYob       = yob       !== "" && cleanText.includes(yob);
        return { isMatch: hasFirstName && (hasLastName || hasYob) };
    }
}