import { apiGet, apiPost, apiPostForm, apiPut, isAuthRedirectError } from '../api.js';
import { guard } from '../core/auth-guard.js';
import {
  ticketStatusLabel,
  ticketPriorityLabel,
  eventTypeLabel,
  eventTypeBadgeClass,
  statusBadgeClass,
  priorityBadgeClass,
} from '../core/constants.js';
import { esc, formatDateTime, extrasName } from '../core/utils.js';
import { bindAttachmentPreview } from '../core/attachment-preview.js';
import {
  eventInhaltHtml,
  syncEventFormFieldGroups,
  buildEventPostBody,
  loadTeamViewerConnectionsIntoSelect,
  sortEventsChronologicalWithAttachmentsLast,
} from '../core/ticket-events.js';

const UUID =
  /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;

const loadingEl = document.getElementById('page-loading');
const badIdEl = document.getElementById('ticket-bad-id');
const errEl = document.getElementById('page-error');
const mainEl = document.getElementById('page-main');
const panelView = document.getElementById('panel-ticket-view');
const panelEdit = document.getElementById('panel-ticket-edit');

function showError(msg) {
  loadingEl.hidden = true;
  badIdEl.hidden = true;
  mainEl.hidden = true;
  errEl.hidden = false;
  errEl.textContent = msg;
}

function fillTicketView(ticket) {
  document.getElementById('ticket-title').textContent = ticket.title;
  const stBadge = document.getElementById('t-status-badge');
  stBadge.textContent = ticketStatusLabel[ticket.status];
  stBadge.className = `badge ${statusBadgeClass[ticket.status] || ''}`;
  document.getElementById('t-priority-label').textContent =
    ticketPriorityLabel[ticket.priority];
  const slaSel = document.getElementById('t-sla-days');
  if (slaSel) {
    slaSel.value =
      ticket.slaDays != null && ticket.slaDays !== ''
        ? String(ticket.slaDays)
        : '';
  }
  document.getElementById('t-description').textContent = ticket.description;

  const mrow = document.getElementById('t-machine-row');
  if (ticket.machine) {
    mrow.hidden = false;
    const mn = extrasName(ticket.machine);
    const link = document.getElementById('t-machine-link');
    link.href = `/machine.html?id=${encodeURIComponent(ticket.machine.id)}`;
    link.textContent = ticket.machine.seriennummer;
    document.getElementById('t-machine-suffix').textContent = mn
      ? ` · ${mn}`
      : '';
  } else {
    mrow.hidden = true;
  }
}

function fillEditForm(ticket) {
  document.getElementById('tu-title').value = ticket.title;
  document.getElementById('tu-desc').value = ticket.description;
  document.getElementById('tu-status').value = ticket.status;
  document.getElementById('tu-priority').value = ticket.priority;
}

function renderEvents(events) {
  const tbody = document.getElementById('events-table-body');
  if (events.length === 0) {
    tbody.innerHTML =
      '<tr><td colspan="3" class="muted">Noch keine Ereignisse.</td></tr>';
    return;
  }
  tbody.innerHTML = events
    .map(
      (ev) => `
            <tr>
              <td class="events-table-time">${esc(formatDateTime(ev.createdAt))}</td>
              <td><span class="badge event-type-badge ${eventTypeBadgeClass[ev.type] || ''}">${esc(eventTypeLabel[ev.type] || ev.type)}</span></td>
              <td class="events-table-desc">${eventInhaltHtml(ev)}</td>
            </tr>`,
    )
    .join('');
}

function showViewMode() {
  panelView.hidden = false;
  panelEdit.hidden = true;
}

function showEditMode() {
  panelView.hidden = true;
  panelEdit.hidden = false;
}

async function viewTicketDetail(id) {
  const [ticket, events] = await Promise.all([
    apiGet(`/tickets/${id}`),
    apiGet(`/tickets/${id}/events`),
  ]);

  let currentTicket = ticket;

  fillTicketView(currentTicket);
  fillEditForm(currentTicket);
  showViewMode();
  renderEvents(sortEventsChronologicalWithAttachmentsLast(events));

  const sect2 = document.getElementById('sect-second-ticket');
  if (currentTicket.machineId) {
    sect2.hidden = false;
  } else {
    sect2.hidden = true;
  }

  const slaSel = document.getElementById('t-sla-days');
  if (slaSel) {
    slaSel.onchange = async () => {
      const v = slaSel.value;
      const slaDays = v === '' ? null : Number(v);
      try {
        const updated = await apiPut(`/tickets/${id}`, { slaDays });
        const evs = await apiGet(`/tickets/${id}/events`);
        currentTicket = updated;
        fillTicketView(updated);
        fillEditForm(updated);
        renderEvents(sortEventsChronologicalWithAttachmentsLast(evs));
      } catch (err) {
        slaSel.value =
          currentTicket.slaDays != null
            ? String(currentTicket.slaDays)
            : '';
        if (isAuthRedirectError(err)) return;
        window.alert(err.message || 'Fehler beim Speichern der Fälligkeit.');
      }
    };
  }

  document.getElementById('btn-t-edit').onclick = () => {
    fillEditForm(currentTicket);
    showEditMode();
  };

  panelEdit.onsubmit = async (e) => {
    e.preventDefault();
    const fd = new FormData(panelEdit);
    await apiPut(`/tickets/${id}`, Object.fromEntries(fd.entries()));
    location.reload();
  };

  document.getElementById('tu-cancel').onclick = () => {
    fillTicketView(currentTicket);
    showViewMode();
  };

  const formEv = document.getElementById('form-ev');
  syncEventFormFieldGroups(formEv);
  formEv.querySelector('#ev-type-sel').onchange = () =>
    syncEventFormFieldGroups(formEv);
  document.getElementById('btn-tv-reload').onclick = () =>
    loadTeamViewerConnectionsIntoSelect();
  formEv.onsubmit = async (e) => {
    e.preventDefault();
    const fd = new FormData(e.target);
    const evType = fd.get('type');
    if (evType === 'ATTACHMENT') {
      const fileInput = document.getElementById('ev-attachment-files');
      const files = fileInput?.files;
      if (!files || files.length === 0) {
        formEv.insertAdjacentHTML(
          'afterbegin',
          '<p class="error tv-form-err">Mindestens eine Datei auswählen.</p>',
        );
        setTimeout(() => {
          document.querySelector('.tv-form-err')?.remove();
        }, 4000);
        return;
      }
      const formData = new FormData();
      formData.append(
        'description',
        String(fd.get('description_attachment') ?? '').trim(),
      );
      for (let i = 0; i < files.length; i += 1) {
        formData.append('files', files[i]);
      }
      await apiPostForm(`/tickets/${id}/events/attachments`, formData);
      e.target.reset();
      syncEventFormFieldGroups(formEv);
      location.reload();
      return;
    }
    let body = buildEventPostBody(id, fd);
    if (body.type === 'REMOTE') {
      const sel = document.getElementById('tv-conn-select');
      const opt = sel?.selectedOptions?.[0];
      if (opt?.value) {
        body.teamviewerId = opt.value;
        const sd = opt.getAttribute('data-start-date');
        const ed = opt.getAttribute('data-end-date');
        if (sd) body.teamviewerStartDate = sd;
        if (ed) body.teamviewerEndDate = ed;
        const n = opt.getAttribute('data-notes');
        if (n && String(n).trim()) body.teamviewerNotes = String(n).trim();
        const dn = opt.getAttribute('data-devicename') || '';
        const u = String(fd.get('description_remote') ?? '').trim();
        if (dn) {
          body.description = u
            ? `${u}\n\nTeamViewer-Gerät: ${dn}`
            : `TeamViewer-Gerät: ${dn}`;
        } else if (u) {
          body.description = u;
        } else {
          body.description = 'Remote-Session (TeamViewer)';
        }
      } else {
        body.description = String(body.description ?? '').trim();
        if (!body.description) {
          formEv.insertAdjacentHTML(
            'afterbegin',
            '<p class="error tv-form-err">Beschreibung oder Gerät auswählen.</p>',
          );
          setTimeout(() => {
            document.querySelector('.tv-form-err')?.remove();
          }, 4000);
          return;
        }
      }
    }
    await apiPost('/events', body);
    e.target.reset();
    syncEventFormFieldGroups(formEv);
    location.reload();
  };

  document.getElementById('form-t2').onsubmit = async (e) => {
    e.preventDefault();
    const fd = new FormData(e.target);
    await apiPost('/tickets', {
      machineId: currentTicket.machineId,
      title: fd.get('title'),
      description: fd.get('description'),
    });
    e.target.reset();
    location.reload();
  };
}

async function init() {
  const st = await guard({ activeNav: 'tickets' });
  if (!st) return;

  const id = new URLSearchParams(location.search).get('id');
  if (!id || !UUID.test(id)) {
    loadingEl.hidden = true;
    badIdEl.hidden = false;
    return;
  }

  loadingEl.hidden = true;
  mainEl.hidden = false;

  bindAttachmentPreview(document.body);

  try {
    await viewTicketDetail(id);
  } catch (e) {
    if (isAuthRedirectError(e)) return;
    showError(e.message || 'Fehler');
  }
}

init();
