import { sendMessage } from '../../shared/state';
import type { Item } from '../../shared/types';

type ViewMode = 'idle' | 'parsing' | 'preview' | 'committing' | 'done';

interface PreviewState {
  items: Item[];
  warnings: Array<{ row: number; title?: string; message: string }>;
  loginCount: number;
  noteCount: number;
}

let mode: ViewMode = 'idle';
let preview: PreviewState | null = null;

export function renderImportPanel(app: HTMLElement): void {
  app.innerHTML = `
    <div class="panel">
      <h1>Import</h1>

      <section class="card" id="import-card">
        <h2>LastPass CSV</h2>
        <p>Pick the CSV exported from LastPass
        (<code>More options → Advanced → Export</code>).
        Items are added to the unlocked vault with fresh IDs.
        Title collisions are kept — no dedup. Failed rows are
        skipped and reported below.</p>

        <input type="file" id="lp-file" accept=".csv,text/csv">

        <div id="lp-preview" class="hidden">
          <p id="lp-preview-text"></p>
          <button id="lp-confirm-btn">Import…</button>
          <button id="lp-cancel-btn">Cancel</button>
        </div>

        <div id="lp-progress" class="hidden">
          <p id="lp-progress-text"></p>
        </div>

        <div id="lp-warnings" class="hidden">
          <h3>Warnings</h3>
          <ul id="lp-warning-list"></ul>
        </div>
      </section>
    </div>
  `;

  wireImport(app);
}

function wireImport(scope: HTMLElement): void {
  const fileEl    = scope.querySelector('#lp-file')          as HTMLInputElement;
  const previewEl = scope.querySelector('#lp-preview')       as HTMLElement;
  const previewTx = scope.querySelector('#lp-preview-text')  as HTMLElement;
  const confirmBt = scope.querySelector('#lp-confirm-btn')   as HTMLButtonElement;
  const cancelBt  = scope.querySelector('#lp-cancel-btn')    as HTMLButtonElement;
  const progressE = scope.querySelector('#lp-progress')      as HTMLElement;
  const progressT = scope.querySelector('#lp-progress-text') as HTMLElement;
  const warningsE = scope.querySelector('#lp-warnings')      as HTMLElement;
  const warningsL = scope.querySelector('#lp-warning-list')  as HTMLElement;

  fileEl.addEventListener('change', async () => {
    const file = fileEl.files?.[0];
    if (!file) return;
    if (mode !== 'idle' && mode !== 'done') return;
    resetPanels(previewEl, progressE, warningsE);

    mode = 'parsing';
    progressE.classList.remove('hidden');
    progressT.textContent = 'Parsing…';

    try {
      const bytes = await file.arrayBuffer();
      const resp = await sendMessage({ type: 'parse_lastpass_csv', bytes });
      progressE.classList.add('hidden');
      if (!resp.ok) {
        previewTx.textContent = `Failed to parse: ${resp.error}`;
        previewEl.classList.remove('hidden');
        confirmBt.classList.add('hidden');
        cancelBt.classList.remove('hidden');
        mode = 'idle';
        return;
      }

      const data = (resp as { ok: true; data: PreviewState }).data;
      preview = aggregate(data);
      previewTx.textContent =
        `${preview.loginCount} logins, ${preview.noteCount} notes, ` +
        `${preview.warnings.length} skipped/warn — proceed?`;
      previewEl.classList.remove('hidden');
      confirmBt.classList.remove('hidden');
      cancelBt.classList.remove('hidden');
      confirmBt.disabled = preview.items.length === 0;
      mode = 'preview';
    } catch (e) {
      progressE.classList.add('hidden');
      previewTx.textContent = `Failed: ${(e as Error).message}`;
      previewEl.classList.remove('hidden');
      mode = 'idle';
    }
  });

  cancelBt.addEventListener('click', () => {
    preview = null;
    fileEl.value = '';
    resetPanels(previewEl, progressE, warningsE);
    mode = 'idle';
  });

  confirmBt.addEventListener('click', async () => {
    if (mode !== 'preview' || !preview) return;
    mode = 'committing';
    confirmBt.disabled = true;
    cancelBt.disabled = true;
    progressE.classList.remove('hidden');
    progressT.textContent = `Importing ${preview.items.length} items…`;

    try {
      const resp = await sendMessage({
        type: 'import_lastpass_commit',
        items: preview.items,
      });
      progressE.classList.add('hidden');
      if (!resp.ok) {
        previewTx.textContent = `Import failed: ${resp.error}`;
        mode = 'idle';
        confirmBt.disabled = false;
        cancelBt.disabled = false;
        return;
      }

      const data = (resp as { ok: true; data: { summary: { itemCount: number } } }).data;
      previewTx.textContent =
        `Imported ${data.summary.itemCount} items. Reload the sidebar to see them.`;
      confirmBt.classList.add('hidden');
      cancelBt.textContent = 'Done';

      if (preview.warnings.length > 0) {
        warningsL.innerHTML = preview.warnings
          .map((w) => {
            const head = w.title ? `row ${w.row} (${escapeText(w.title)})` : `row ${w.row}`;
            return `<li>${head}: ${escapeText(w.message)}</li>`;
          })
          .join('');
        warningsE.classList.remove('hidden');
      }
      mode = 'done';
    } catch (e) {
      progressE.classList.add('hidden');
      previewTx.textContent = `Failed: ${(e as Error).message}`;
      confirmBt.disabled = false;
      cancelBt.disabled = false;
      mode = 'idle';
    }
  });
}

function aggregate(data: PreviewState): PreviewState {
  let loginCount = 0;
  let noteCount  = 0;
  for (const item of data.items) {
    if (item.type === 'login')             loginCount += 1;
    else if (item.type === 'secure_note')  noteCount  += 1;
  }
  return { ...data, loginCount, noteCount };
}

function resetPanels(preview: HTMLElement, progress: HTMLElement, warnings: HTMLElement): void {
  preview.classList.add('hidden');
  progress.classList.add('hidden');
  warnings.classList.add('hidden');
}

function escapeText(s: string): string {
  return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}

export function teardown(): void {
  preview = null;
  mode = 'idle';
}
