{{define "webmail_compose.html"}}
<!DOCTYPE html>
<html lang="en" data-bs-theme="dark">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Compose - Webmail</title>
    <link href="/webmail/static/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/webmail/static/vendor/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
    <link href="/webmail/static/vendor/quill/quill.snow.css" rel="stylesheet">
    <style>
        :root { --cw-bg: #1e1e1e; --cw-panel: #262626; --cw-border: #404040; --cw-text: #e0e0e0; --cw-muted: #9a9a9a; }
        html, body { height: 100%; margin: 0; overflow: hidden; }
        body { background-color: var(--cw-bg); color: var(--cw-text); font-size: .875rem; }

        .compose-shell { display: flex; flex-direction: column; height: 100vh; }

        .compose-actionbar { flex: 0 0 auto; display: flex; align-items: center; gap: .5rem; padding: .5rem .75rem; border-bottom: 1px solid var(--cw-border); background-color: var(--cw-panel); flex-wrap: wrap; }
        .compose-actionbar .from-email { font-size: .8rem; color: var(--cw-muted); }
        .compose-actionbar select.from-select { max-width: 220px; }

        .compose-fields { flex: 0 0 auto; padding: 0 .75rem; }
        .field-row { display: flex; align-items: center; border-bottom: 1px solid var(--cw-border); padding: .3rem 0; }
        .field-row .field-label { width: 42px; flex: 0 0 auto; color: var(--cw-muted); font-size: .8rem; }
        .field-row input.bare-input { flex: 1 1 auto; min-width: 0; border: 0; background: transparent; color: var(--cw-text); outline: none; font-size: .85rem; padding: .2rem 0; }
        .field-row input.bare-input::placeholder { color: var(--cw-muted); }
        .cc-bcc-toggle { flex: 0 0 auto; font-size: .75rem; color: #6ea8fe; cursor: pointer; margin-left: .5rem; white-space: nowrap; }
        .cc-bcc-toggle:hover { text-decoration: underline; }
        .subject-row input.bare-input { font-size: .95rem; padding: .4rem 0; }

        .crypto-row { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; padding: .4rem 0; font-size: .78rem; color: var(--cw-muted); }
        .crypto-row .form-check { margin-bottom: 0; }
        .crypto-row .form-check-label { font-size: .8rem; }

        .editor-wrap { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; padding: 0 .75rem .5rem; }
        .editor-wrap.drag-over { outline: 2px dashed #6ea8fe; outline-offset: -4px; }
        #editor { flex: 1 1 auto; min-height: 0; background-color: #fff; color: #000; }
        .ql-toolbar.ql-snow { flex: 0 0 auto; background-color: #333; border-color: var(--cw-border); border-top-left-radius: .375rem; border-top-right-radius: .375rem; }
        .ql-container.ql-snow { border-color: var(--cw-border); border-bottom-left-radius: .375rem; border-bottom-right-radius: .375rem; }

        /* Quill's default snow-theme icons are near-black (#444) — invisible on a dark
           toolbar. Light stroke/fill + light picker text restores contrast. */
        .ql-snow .ql-stroke { stroke: #c8c8c8; }
        .ql-snow .ql-fill, .ql-snow .ql-stroke.ql-fill { fill: #c8c8c8; }
        .ql-snow .ql-picker { color: #c8c8c8; }
        .ql-snow .ql-picker-label { color: #c8c8c8; border-color: transparent; }
        .ql-snow .ql-picker-options { background-color: var(--cw-panel); border-color: var(--cw-border); }
        .ql-snow .ql-picker-item { color: #c8c8c8; }
        .ql-toolbar.ql-snow button:hover, .ql-toolbar.ql-snow button.ql-active,
        .ql-toolbar.ql-snow .ql-picker-label:hover, .ql-toolbar.ql-snow .ql-picker-label.ql-active,
        .ql-toolbar.ql-snow .ql-picker-item:hover { color: #fff; }
        .ql-toolbar.ql-snow button:hover .ql-stroke, .ql-toolbar.ql-snow button.ql-active .ql-stroke,
        .ql-toolbar.ql-snow button:hover .ql-fill, .ql-toolbar.ql-snow button.ql-active .ql-fill { stroke: #fff; }
        .ql-snow .ql-tooltip { background-color: var(--cw-panel); color: var(--cw-text); border-color: var(--cw-border); box-shadow: 0 2px 8px rgba(0,0,0,.4); }
        .ql-snow .ql-tooltip input[type="text"] { background-color: var(--cw-bg); color: var(--cw-text); border-color: var(--cw-border); }

        .attachment-list:not(:empty) { padding: .4rem 0; display: flex; flex-wrap: wrap; gap: .4rem; }
    </style>
</head>
<body>
    {{template "csrf_script" .}}
    <div class="toast-container position-fixed top-0 end-0 p-3" style="z-index: 1090;">
        {{range .flashes}}
        <div class="toast align-items-center text-bg-{{if eq .Category "error"}}danger{{else}}{{.Category}}{{end}} border-0" role="alert" aria-live="assertive" aria-atomic="true">
            <div class="d-flex">
                <div class="toast-body">
                    <i class="bi bi-{{if eq .Category "error"}}exclamation-triangle{{else if eq .Category "success"}}check-circle{{else}}info-circle{{end}} me-2"></i>
                    {{.Message}}
                </div>
                <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
            </div>
        </div>
        {{end}}
    </div>

    <form id="composeForm" method="POST" action="/webmail/mail/compose" enctype="multipart/form-data" class="compose-shell">
        <input type="hidden" name="in_reply_to" value="{{.in_reply_to}}">
        <input type="hidden" name="draft_id" value="{{.draft_id}}">

        <div class="compose-actionbar">
            <button type="submit" class="btn btn-primary btn-sm"><i class="bi bi-send me-1"></i>Send</button>
            <button type="submit" formaction="/webmail/mail/save-draft" formnovalidate class="btn btn-outline-light btn-sm"><i class="bi bi-save2 me-1"></i>Save</button>
            <small class="from-email" id="autosaveStatus" style="display: none;"></small>
            <button type="button" id="attachBtn" class="btn btn-outline-light btn-sm" title="Attach files"><i class="bi bi-paperclip"></i></button>
            <input type="file" id="attachment_input" name="attachments" multiple style="display: none;">
            {{if .signatures}}
            <select class="form-select form-select-sm" id="signatureSelect" style="width: auto;" title="Signature">
                <option value="">No signature</option>
                {{range .signatures}}<option value="{{.ID}}" {{if eq $.default_signature_id .ID}}selected{{end}}>{{.Name}}</option>{{end}}
            </select>
            {{range .signatures}}<div class="sig-data" data-sig-id="{{.ID}}" style="display: none;">{{.ContentHTML | safe}}</div>{{end}}
            {{end}}
            <script type="application/json" id="signatureDefaultsData">{{.signature_defaults_json}}</script>
            <script>var composeForReply = {{.compose_for_reply}};</script>
            <div class="ms-auto d-flex align-items-center gap-2">
                {{if .send_as_options}}
                <select class="form-select form-select-sm from-select" name="from">
                    <option value="{{.mailbox.Email}}">{{.mailbox.Email}}</option>
                    {{range .send_as_options}}<option value="{{.}}">{{.}}</option>{{end}}
                </select>
                {{else}}
                <span class="from-email">{{.mailbox.Email}}</span>
                {{end}}
                <a href="/webmail/mail/INBOX" class="btn btn-sm btn-outline-light" title="Close"><i class="bi bi-x-lg"></i></a>
            </div>
        </div>

        <div class="compose-fields">
            <div class="field-row">
                <label class="field-label">To</label>
                <input type="text" class="bare-input recipient-input" name="to" value="{{.to}}" placeholder="recipient@example.com, another@example.com" list="recipientSuggestions" autocomplete="off" required>
                <span class="cc-bcc-toggle" id="showCc">Cc</span>
                <span class="cc-bcc-toggle" id="showBcc">Bcc</span>
            </div>
            <div class="field-row" id="ccRow" style="display: none;">
                <label class="field-label">Cc</label>
                <input type="text" class="bare-input recipient-input" name="cc" value="{{.cc}}" list="recipientSuggestions" autocomplete="off">
            </div>
            <div class="field-row" id="bccRow" style="display: none;">
                <label class="field-label">Bcc</label>
                <input type="text" class="bare-input recipient-input" name="bcc" value="{{.bcc}}" list="recipientSuggestions" autocomplete="off">
            </div>
            <datalist id="recipientSuggestions"></datalist>
            <div class="field-row subject-row">
                <input type="text" class="bare-input" name="subject" value="{{.subject}}" placeholder="Add a subject">
            </div>
            <div class="crypto-row">
                <div class="form-check">
                    <input class="form-check-input" type="checkbox" name="smime_sign" value="1" id="smime_sign">
                    <label class="form-check-label" for="smime_sign"><i class="bi bi-pen me-1"></i>Sign (S/MIME)</label>
                </div>
                <div class="form-check">
                    <input class="form-check-input" type="checkbox" name="pgp_encrypt" value="1" id="pgp_encrypt">
                    <label class="form-check-label" for="pgp_encrypt"><i class="bi bi-lock me-1"></i>Encrypt (PGP)</label>
                </div>
                {{if gt (len .smime_identities) 1}}
                <div id="smime_identity_row" style="display: none;">
                    <select class="form-select form-select-sm" name="smime_identity_id">
                        {{range .smime_identities}}<option value="{{.ID}}">Certificate expiring {{.NotAfter.Format "2006-01-02"}}</option>{{end}}
                    </select>
                </div>
                {{end}}
                <div id="pgp_recipient_row" style="display: none;">
                    {{if .pgp_contacts}}
                    <select class="form-select form-select-sm" name="pgp_recipient_id" multiple size="3" style="min-width: 220px;">
                        {{range .pgp_contacts}}<option value="{{.ID}}">{{if .Label}}{{.Label}}{{else}}{{.Email}}{{end}} — {{.Fingerprint}}</option>{{end}}
                    </select>
                    {{else}}
                    <span>No PGP contacts yet — add one on the Certs page.</span>
                    {{end}}
                </div>
                <a href="/webmail/certs" class="ms-auto text-muted">Manage certificates</a>
            </div>
            <div id="attachment_list" class="attachment-list"></div>
        </div>

        <div class="editor-wrap" id="editorWrap">
            <div id="editor"></div>
            <textarea name="body_html" style="display: none;"></textarea>
        </div>
        <div id="body_html_seed" style="display: none;">{{.body_html}}</div>
    </form>

    <script src="/webmail/static/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
    <script src="/webmail/static/vendor/quill/quill.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            document.querySelectorAll('.toast').forEach(function(el) { new bootstrap.Toast(el, {delay: 5000}).show(); });
        });

        // Quill's default clipboard module already turns a pasted screenshot into an
        // embedded base64 <img> — that's what makes "paste a screenshot like Outlook"
        // work with no extra code here.
        var quill = new Quill('#editor', {
            theme: 'snow',
            modules: {
                toolbar: [
                    ['bold', 'italic', 'underline', 'strike'],
                    [{ list: 'ordered' }, { list: 'bullet' }],
                    [{ color: [] }, { background: [] }],
                    [{ size: ['small', false, 'large', 'huge'] }],
                    ['link', 'image'],
                    ['clean'],
                ],
            },
        });
        // Signature tracking: the signature is kept as a plain-paragraph Delta range
        // (index/length) rather than a DOM marker div. A wrapping <div> set directly on
        // quill.root gets silently discarded by Quill's own MutationObserver within one
        // update cycle (it isn't a recognized block type) — confirmed live, so signature
        // content is inserted via Quill's own clipboard API instead, which turns it into
        // real paragraph blots that survive.
        var sigRange = null; // {index, length} of the signature currently in the editor, or null

        function insertSignature(index, html) {
            if (!html) return null;
            const before = quill.getLength();
            quill.clipboard.dangerouslyPasteHTML(index, html);
            return { index: index, length: quill.getLength() - before };
        }

        function removeSignature() {
            if (sigRange && sigRange.length > 0) quill.deleteText(sigRange.index, sigRange.length);
            sigRange = null;
        }

        (function() {
            const seed = document.getElementById('body_html_seed');
            if (!seed || !seed.innerHTML.trim()) return;
            const parsed = document.createElement('div');
            parsed.innerHTML = seed.innerHTML;
            const sigEl = parsed.querySelector('#mailSignatureBlock');
            let sigHTML = '';
            if (sigEl) {
                sigHTML = sigEl.innerHTML;
                sigEl.remove();
            }
            quill.root.innerHTML = parsed.innerHTML;
            // Reply/forward seeds start with an empty line above the quoted
            // original (see composeCursorHome, webmail_compose.go) — put the
            // cursor there so typing starts above the quote, not inside or after it.
            quill.setSelection(0, 0);
            quill.focus();
            if (sigHTML) {
                // The backend always inserts the signature immediately after that
                // leading empty paragraph (index 1), before any quoted/forwarded
                // text — see webmailComposeForm.
                sigRange = insertSignature(1, sigHTML);
                quill.setSelection(0, 0);
            }
        })();

        // Signature picker: swaps the currently-inserted signature (tracked via
        // sigRange above) for a different one, or removes it. Picking one when none
        // exists yet appends it at the end of the body.
        (function() {
            const select = document.getElementById('signatureSelect');
            if (!select) return;
            const sigHTML = {};
            document.querySelectorAll('.sig-data').forEach(function(el) { sigHTML[el.dataset.sigId] = el.innerHTML; });

            select.addEventListener('change', function() {
                const insertAt = sigRange ? sigRange.index : Math.max(0, quill.getLength() - 1);
                removeSignature();
                if (!select.value) return;
                sigRange = insertSignature(insertAt, sigHTML[select.value] || '');
            });

            // Switching "From" (a send-as alias) re-picks whichever signature is that
            // address's own default — see composeFormData's signature_defaults_json.
            // Only ever auto-*switches* to a different default; it never removes a
            // signature the user picked by hand if that address has none of its own
            // (falls back to "leave whatever's already inserted" instead of clearing it).
            const fromSelect = document.querySelector('.from-select');
            const defaultsDataEl = document.getElementById('signatureDefaultsData');
            if (fromSelect && defaultsDataEl) {
                let signatureDefaults = {};
                try { signatureDefaults = JSON.parse(defaultsDataEl.textContent) || {}; } catch (e) { signatureDefaults = {}; }
                fromSelect.addEventListener('change', function() {
                    const entry = signatureDefaults[fromSelect.value];
                    if (!entry) return;
                    const newId = composeForReply ? entry.reply : entry.new;
                    if (!newId) return;
                    select.value = String(newId);
                    select.dispatchEvent(new Event('change'));
                });
            }
        })();

        // Cc/Bcc start hidden (Outlook-style) unless prefilled (e.g. reply-all sets
        // Cc) — clicking a toggle reveals its row and focuses the field, same as
        // clicking "Cc"/"Bcc" in a real mail client.
        (function() {
            function wireToggle(toggleId, rowId, fieldName) {
                const toggle = document.getElementById(toggleId);
                const row = document.getElementById(rowId);
                const field = row.querySelector('[name="' + fieldName + '"]');
                if (field.value.trim()) {
                    row.style.display = 'flex';
                    toggle.style.display = 'none';
                } else {
                    toggle.addEventListener('click', function() {
                        row.style.display = 'flex';
                        toggle.style.display = 'none';
                        field.focus();
                    });
                }
            }
            wireToggle('showCc', 'ccRow', 'cc');
            wireToggle('showBcc', 'bccRow', 'bcc');
        })();

        // Attachments accumulate across multiple picks/drops instead of the native
        // file input's default "replace the whole selection" behavior — a DataTransfer
        // is the only way to build an editable FileList, so it's kept as the source of
        // truth and re-assigned onto the real (hidden) input before every render.
        // Drag-and-drop works anywhere over the message area, matching a real client —
        // there's no dedicated dropzone box taking up space when empty.
        (function() {
            const form = document.getElementById('composeForm');
            const dropTarget = document.getElementById('editorWrap');
            const attachBtn = document.getElementById('attachBtn');
            const input = document.getElementById('attachment_input');
            const list = document.getElementById('attachment_list');
            let staged = new DataTransfer();

            function render() {
                input.files = staged.files;
                list.innerHTML = '';
                Array.from(staged.files).forEach(function(file, i) {
                    const chip = document.createElement('span');
                    chip.className = 'badge text-bg-secondary d-flex align-items-center gap-1 py-2 px-2';
                    chip.textContent = file.name + ' (' + Math.round(file.size / 1024) + ' KB)';
                    const remove = document.createElement('button');
                    remove.type = 'button';
                    remove.className = 'btn-close btn-close-white ms-1';
                    remove.style.fontSize = '0.65rem';
                    remove.setAttribute('aria-label', 'Remove');
                    remove.addEventListener('click', function() { removeFile(i); });
                    chip.appendChild(remove);
                    list.appendChild(chip);
                });
            }

            function addFiles(fileList) {
                Array.from(fileList).forEach(function(file) { staged.items.add(file); });
                render();
            }

            function removeFile(index) {
                const next = new DataTransfer();
                Array.from(staged.files).forEach(function(file, i) { if (i !== index) next.items.add(file); });
                staged = next;
                render();
            }

            attachBtn.addEventListener('click', function() { input.click(); });
            input.addEventListener('change', function() { addFiles(input.files); });
            form.addEventListener('dragover', function(e) { e.preventDefault(); dropTarget.classList.add('drag-over'); });
            form.addEventListener('dragleave', function(e) { if (e.target === form) dropTarget.classList.remove('drag-over'); });
            form.addEventListener('drop', function(e) {
                e.preventDefault();
                dropTarget.classList.remove('drag-over');
                if (e.dataTransfer.files.length) addFiles(e.dataTransfer.files);
            });

            window.__composeAttachmentCount = function() { return staged.files.length; };
        })();

        // The identity picker (when there's more than one S/MIME certificate) only
        // matters for signing — encrypting alone never touches it.
        (function() {
            const signCheckbox = document.getElementById('smime_sign');
            const identityRow = document.getElementById('smime_identity_row');
            if (!identityRow) return;
            function update() { identityRow.style.display = signCheckbox.checked ? '' : 'none'; }
            signCheckbox.addEventListener('change', update);
            update();
        })();

        // The recipient-key picker only matters for encrypting.
        (function() {
            const encryptCheckbox = document.getElementById('pgp_encrypt');
            const recipientRow = document.getElementById('pgp_recipient_row');
            function update() { recipientRow.style.display = encryptCheckbox.checked ? '' : 'none'; }
            encryptCheckbox.addEventListener('change', update);
            update();
        })();

        // Recipient autocomplete: suggests addresses this mailbox has exchanged mail
        // with, matching the fragment being typed after the last comma (a
        // To/Cc/Bcc field holds a comma-separated address list, so only the
        // in-progress fragment should be matched/replaced, not the whole value).
        (function() {
            const datalist = document.getElementById('recipientSuggestions');
            let debounceTimer = null;
            document.querySelectorAll('.recipient-input').forEach(function(input) {
                input.addEventListener('input', function() {
                    clearTimeout(debounceTimer);
                    const value = input.value;
                    const splitAt = value.lastIndexOf(',') + 1;
                    const fragment = value.slice(splitAt).trim();
                    if (!fragment) { datalist.innerHTML = ''; return; }
                    debounceTimer = setTimeout(function() {
                        fetch('/webmail/mail/recipients?q=' + encodeURIComponent(fragment))
                            .then(function(r) { return r.json(); })
                            .then(function(suggestions) {
                                datalist.innerHTML = '';
                                const prefix = value.slice(0, splitAt);
                                (suggestions || []).forEach(function(addr) {
                                    const opt = document.createElement('option');
                                    opt.value = (prefix ? prefix + ' ' : '') + addr;
                                    datalist.appendChild(opt);
                                });
                            })
                            .catch(function() {});
                    }, 200);
                });
            });
        })();

        // Draft autosave: periodically saves in the background if anything's
        // changed since the last autosave, reusing the existing Save Draft endpoint
        // exactly as a manual click would submit it — no backend change needed. The
        // browser follows the redirect to /webmail/mail/compose?draft=ID&folder=Drafts,
        // and that URL's draft param becomes the new draft_id so the next autosave (or
        // manual Send) updates the same draft instead of creating a new one.
        // Deliberately text-only: attachments aren't re-uploaded on every tick (a
        // real Save or Send still includes them) to avoid repeatedly re-sending
        // large file data in the background.
        (function() {
            const form = document.getElementById('composeForm');
            const draftIdInput = document.querySelector('[name="draft_id"]');
            const status = document.getElementById('autosaveStatus');
            let lastSaved = null;

            function snapshot() {
                return JSON.stringify({
                    to: document.querySelector('[name="to"]').value,
                    cc: document.querySelector('[name="cc"]').value,
                    bcc: document.querySelector('[name="bcc"]').value,
                    subject: document.querySelector('[name="subject"]').value,
                    body: quill.root.innerHTML,
                });
            }

            async function autosave() {
                const current = snapshot();
                if (current === lastSaved) return;
                const subject = document.querySelector('[name="subject"]').value.trim();
                const to = document.querySelector('[name="to"]').value.trim();
                if (!to && !subject && !quill.getText().trim()) return; // nothing worth saving yet

                document.querySelector('[name="body_html"]').value = quill.root.innerHTML;
                const formData = new FormData(form);
                formData.delete('attachments');
                try {
                    const resp = await fetch('/webmail/mail/save-draft', { method: 'POST', body: formData });
                    if (resp.ok) {
                        const draftId = new URL(resp.url).searchParams.get('draft');
                        if (draftId) draftIdInput.value = draftId;
                        lastSaved = current;
                        if (status) {
                            status.textContent = 'Saved ' + new Date().toLocaleTimeString();
                            status.style.display = '';
                        }
                    }
                } catch (e) { /* offline or a transient error — retried next interval */ }
            }

            setInterval(autosave, 30000);
        })();

        // Enter in a single-line field (To/Cc/Bcc/Subject) implicitly submits the
        // form — that's how a stray keypress used to send a blank email.
        ['to', 'cc', 'bcc', 'subject'].forEach(function(name) {
            const el = document.querySelector('[name="' + name + '"]');
            if (el) {
                el.addEventListener('keydown', function(e) {
                    if (e.key === 'Enter') { e.preventDefault(); }
                });
            }
        });

        document.getElementById('composeForm').addEventListener('submit', function(e) {
            document.querySelector('[name="body_html"]').value = quill.root.innerHTML;
            // Save (formaction=save-draft) deliberately skips the subject/body-required
            // guard below — a draft can be incomplete by definition.
            const isDraftSave = e.submitter && e.submitter.getAttribute('formaction') === '/webmail/mail/save-draft';
            if (isDraftSave) return;
            const subject = document.querySelector('[name="subject"]').value.trim();
            const body = quill.getText().trim();
            const hasAttachments = window.__composeAttachmentCount && window.__composeAttachmentCount() > 0;
            if (!subject) {
                e.preventDefault();
                alert('Please add a subject before sending.');
                return;
            }
            if (!body && !hasAttachments) {
                e.preventDefault();
                alert('Please write a message or add an attachment before sending.');
                return;
            }
        });
    </script>
</body>
</html>
{{end}}
