const form = document.querySelector('#contractForm');
const templateSelect = document.querySelector('#template');
const submitButton = document.querySelector('#submitButton');
const downloadButton = document.querySelector('#downloadButton');
const shareButton = document.querySelector('#shareButton');
const message = document.querySelector('#message');
const resultTitle = document.querySelector('#resultTitle');
const connectionStatus = document.querySelector('#connectionStatus');
const previewFrame = document.querySelector('#previewFrame');
const previewLoading = document.querySelector('#previewLoading');
const previewOpenBtn = document.querySelector('#previewOpenBtn');

let currentPdfBlob = null;
let currentPdfFileName = '租屋契約.pdf';

loadTemplates();
setDefaultLeaseDates();

document.getElementById('leaseStart').addEventListener('change', (e) => {
  const [y, m, d] = e.target.value.split('-').map(Number);
  if (!y || !m || !d) return;
  document.getElementById('leaseEnd').value = toDateInputValue(computeLeaseEnd(new Date(y, m - 1, d)));
  schedulePreview();
});

templateSelect.addEventListener('change', () => {
  loadTemplateDefaults(templateSelect.value);
  loadPreview();
});

let previewTimer = null;
function schedulePreview() {
  clearTimeout(previewTimer);
  previewTimer = setTimeout(loadPreview, 600);
}

form.querySelectorAll('input').forEach((el) => el.addEventListener('input', schedulePreview));

form.addEventListener('submit', async (event) => {
  event.preventDefault();
  setBusy(true);
  resetPdf();

  try {
    const formData = new FormData(form);
    const response = await fetch('/api/contracts/pdf', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        template: formData.get('template'),
        monthlyRent: formData.get('monthlyRent'),
        paymentDay: formData.get('paymentDay'),
        deposit: formData.get('deposit'),
        cleaningFee: formData.get('cleaningFee'),
        leaseStart: formData.get('leaseStart'),
        leaseEnd: formData.get('leaseEnd'),
      }),
    });

    if (!response.ok) {
      const errorBody = await response.json().catch(() => ({}));
      throw new Error(errorBody.error || 'PDF 產生失敗。');
    }

    currentPdfBlob = await response.blob();
    currentPdfFileName = getFileNameFromDisposition(response.headers.get('Content-Disposition'))
      || buildDefaultFileName(formData.get('template'));

    resultTitle.textContent = 'PDF 已產生';
    message.textContent = currentPdfFileName;
    downloadButton.disabled = false;
    shareButton.disabled = !canShareCurrentPdf();
  } catch (error) {
    resultTitle.textContent = '產生失敗';
    message.textContent = error.message;
  } finally {
    setBusy(false);
  }
});

downloadButton.addEventListener('click', () => {
  if (!currentPdfBlob) return;
  downloadPdf();
});

shareButton.addEventListener('click', async () => {
  if (!currentPdfBlob) return;

  const file = new File([currentPdfBlob], currentPdfFileName, { type: 'application/pdf' });
  if (!navigator.canShare || !navigator.canShare({ files: [file] })) {
    downloadPdf();
    return;
  }

  try {
    await navigator.share({ title: '租屋契約 PDF', files: [file] });
  } catch (error) {
    if (error.name !== 'AbortError') {
      message.textContent = '分享失敗，已保留下載按鈕。';
    }
  }
});

async function loadTemplates() {
  try {
    const response = await fetch('/api/templates');
    if (!response.ok) throw new Error('無法讀取範本。');

    const body = await response.json();
    templateSelect.replaceChildren(
      ...body.templates.map((name) => new Option(name, name)),
    );

    if (body.templates.length === 0) {
      templateSelect.append(new Option('templates 資料夾沒有範本', ''));
      templateSelect.disabled = true;
      submitButton.disabled = true;
      connectionStatus.textContent = '缺少範本';
      message.textContent = '請先將 .docx 範本放進 templates 資料夾。';
      return;
    }

    connectionStatus.textContent = '可使用';
    loadTemplateDefaults(templateSelect.value);
    loadPreview();
  } catch (error) {
    templateSelect.append(new Option('讀取失敗', ''));
    templateSelect.disabled = true;
    submitButton.disabled = true;
    connectionStatus.textContent = '離線';
    message.textContent = error.message;
  }
}

async function loadTemplateDefaults(name) {
  if (!name) return;
  try {
    const res = await fetch(`/api/templates/${encodeURIComponent(name)}/defaults`);
    if (!res.ok) return;
    const defaults = await res.json();
    if (defaults.monthlyRent) form.elements.monthlyRent.value = defaults.monthlyRent;
    if (defaults.paymentDay)  form.elements.paymentDay.value  = defaults.paymentDay;
    if (defaults.deposit)     form.elements.deposit.value     = defaults.deposit;
    if (defaults.cleaningFee) form.elements.cleaningFee.value = defaults.cleaningFee;
  } catch {}
}

let previewGen = 0;
let previewAbortController = null;
let previewBlobUrl = null;

async function loadPreview() {
  const name = templateSelect.value;
  if (!name) {
    previewFrame.src = 'about:blank';
    previewLoading.hidden = true;
    return;
  }

  if (previewAbortController) previewAbortController.abort();
  previewAbortController = new AbortController();
  const { signal } = previewAbortController;
  const gen = ++previewGen;

  const formData = new FormData(form);
  const params = new URLSearchParams({
    monthlyRent: formData.get('monthlyRent') || '',
    paymentDay:  formData.get('paymentDay')  || '',
    deposit:     formData.get('deposit')     || '',
    cleaningFee: formData.get('cleaningFee') || '',
    leaseStart:  formData.get('leaseStart')  || '',
    leaseEnd:    formData.get('leaseEnd')    || '',
  });

  previewLoading.hidden = false;

  try {
    const res = await fetch(
      `/api/templates/${encodeURIComponent(name)}/preview?${params}`,
      { signal },
    );
    if (!res.ok) throw new Error('preview failed');
    const blob = await res.blob();
    if (gen !== previewGen) return;

    if (previewBlobUrl) URL.revokeObjectURL(previewBlobUrl);
    previewBlobUrl = URL.createObjectURL(blob);
    previewFrame.src = `${previewBlobUrl}#toolbar=0`;
    previewOpenBtn.href = previewBlobUrl;
    previewOpenBtn.hidden = false;
  } catch {
    // AbortError 或其他錯誤都忽略，交給 finally 處理
  } finally {
    if (gen === previewGen) previewLoading.hidden = true;
  }
}

function setBusy(isBusy) {
  submitButton.disabled = isBusy || templateSelect.disabled;
  submitButton.textContent = isBusy ? '產生中' : '產生 PDF';
}

function resetPdf() {
  currentPdfBlob = null;
  downloadButton.disabled = true;
  shareButton.disabled = true;
  resultTitle.textContent = '產生中';
  message.textContent = '正在建立 PDF。';
}

function canShareCurrentPdf() {
  if (!currentPdfBlob || !navigator.canShare) return false;
  const file = new File([currentPdfBlob], currentPdfFileName, { type: 'application/pdf' });
  return navigator.canShare({ files: [file] });
}

function downloadPdf() {
  const url = URL.createObjectURL(currentPdfBlob);
  const link = document.createElement('a');
  link.href = url;
  link.download = currentPdfFileName;
  document.body.append(link);
  link.click();
  link.remove();
  URL.revokeObjectURL(url);
}

function getFileNameFromDisposition(disposition) {
  if (!disposition) return '';
  const utf8Match = disposition.match(/filename\*=UTF-8''([^;]+)/i);
  if (utf8Match) return decodeURIComponent(utf8Match[1]);
  const asciiMatch = disposition.match(/filename="([^"]+)"/i);
  return asciiMatch ? asciiMatch[1] : '';
}

function buildDefaultFileName(templateName) {
  const baseName = String(templateName || '租屋契約').replace(/\.[^.]+$/, '');
  return `${baseName}.pdf`;
}

function setDefaultLeaseDates() {
  const start = new Date();
  start.setDate(1);
  start.setMonth(start.getMonth() + 1);
  document.getElementById('leaseStart').value = toDateInputValue(start);
  document.getElementById('leaseEnd').value = toDateInputValue(computeLeaseEnd(start));
}

function computeLeaseEnd(startDate) {
  const end = new Date(startDate);
  end.setFullYear(end.getFullYear() + 1);
  end.setDate(end.getDate() - 1);
  return end;
}

function toDateInputValue(date) {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, '0');
  const d = String(date.getDate()).padStart(2, '0');
  return `${y}-${m}-${d}`;
}
