import * as Blockly from 'blockly';

const BROWSER_STORAGE_KEY = 'esp32block_projects';

let workspace = null;
let captureOutput = null;
let execCode = null;
let writeFile = null;
let checkConnected = null;

let browserList, deviceList;
let browserNameInput, deviceNameInput;
let browserSaveBtn, browserLoadBtn, browserDeleteBtn;
let deviceSaveBtn, deviceLoadBtn, deviceDeleteBtn;
let deviceStatus;

let browserSelected = null;
let deviceSelected = null;

export function initProjectsDialog(deps) {
  workspace = deps.workspace;
  captureOutput = deps.captureDeviceOutput;
  execCode = deps.executeCode;
  writeFile = deps.writeFileToDevice;
  checkConnected = deps.isConnected;

  browserList = document.getElementById('browser-list');
  deviceList = document.getElementById('device-list');
  browserNameInput = document.getElementById('browser-save-name');
  deviceNameInput = document.getElementById('device-save-name');
  browserSaveBtn = document.getElementById('browser-save-btn');
  browserLoadBtn = document.getElementById('browser-load-btn');
  browserDeleteBtn = document.getElementById('browser-delete-btn');
  deviceSaveBtn = document.getElementById('device-save-btn');
  deviceLoadBtn = document.getElementById('device-load-btn');
  deviceDeleteBtn = document.getElementById('device-delete-btn');
  deviceStatus = document.getElementById('device-status');

  browserSaveBtn.addEventListener('click', saveBrowser);
  browserLoadBtn.addEventListener('click', loadBrowser);
  browserDeleteBtn.addEventListener('click', deleteBrowser);
  deviceSaveBtn.addEventListener('click', saveDevice);
  deviceLoadBtn.addEventListener('click', loadDevice);
  deviceDeleteBtn.addEventListener('click', deleteDevice);

  refreshBrowserList();
  refreshDeviceList();
}

export function refreshAll() {
  refreshBrowserList();
  refreshDeviceList();
}

// ─── Browser column ──────────────────────────────────────

function getBrowserProjects() {
  try {
    return JSON.parse(localStorage.getItem(BROWSER_STORAGE_KEY) || '{}');
  } catch { return {}; }
}

function setBrowserProjects(projects) {
  localStorage.setItem(BROWSER_STORAGE_KEY, JSON.stringify(projects));
}

function refreshBrowserList() {
  const projects = getBrowserProjects();
  const names = Object.keys(projects).sort();
  browserList.innerHTML = '';
  browserSelected = null;
  updateBrowserButtons();

  if (names.length === 0) {
    browserList.innerHTML = '<li class="empty-msg">No saved projects</li>';
    return;
  }

  for (const name of names) {
    const li = document.createElement('li');
    li.textContent = name;
    li.addEventListener('click', () => selectBrowserItem(name, li));
    li.addEventListener('dblclick', () => { selectBrowserItem(name, li); loadBrowser(); });
    browserList.appendChild(li);
  }
}

function selectBrowserItem(name, li) {
  browserList.querySelectorAll('li').forEach(el => el.classList.remove('selected'));
  li.classList.add('selected');
  browserSelected = name;
  browserNameInput.value = name;
  updateBrowserButtons();
}

function updateBrowserButtons() {
  browserLoadBtn.disabled = !browserSelected;
  browserDeleteBtn.disabled = !browserSelected;
}

function saveBrowser() {
  const name = browserNameInput.value.trim();
  if (!name) return;
  const projects = getBrowserProjects();
  projects[name] = Blockly.serialization.workspaces.save(workspace);
  setBrowserProjects(projects);
  browserNameInput.value = '';
  refreshBrowserList();
}

function loadBrowser() {
  if (!browserSelected) return;
  const projects = getBrowserProjects();
  const state = projects[browserSelected];
  if (!state) return;
  Blockly.serialization.workspaces.load(state, workspace);
}

function deleteBrowser() {
  if (!browserSelected) return;
  const projects = getBrowserProjects();
  delete projects[browserSelected];
  setBrowserProjects(projects);
  refreshBrowserList();
}

// ─── Device column ───────────────────────────────────────

export async function refreshDeviceList() {
  deviceList.innerHTML = '';
  deviceSelected = null;
  updateDeviceButtons();

  if (!checkConnected()) {
    deviceStatus.textContent = 'Connect a device to see its projects';
    deviceSaveBtn.disabled = true;
    deviceList.innerHTML = '<li class="empty-msg">Not connected</li>';
    return;
  }

  deviceStatus.textContent = 'Loading...';
  deviceSaveBtn.disabled = false;

  try {
    const raw = await captureOutput(
      "import os\n" +
      "for f in os.listdir('/'):\n" +
      "  if f.endswith('.blk'): print(f)"
    );
    const files = raw.trim().split('\n').filter(Boolean).map(f => f.trim());
    deviceList.innerHTML = '';

    if (files.length === 0) {
      deviceList.innerHTML = '<li class="empty-msg">No saved projects</li>';
      deviceStatus.textContent = '';
      return;
    }

    for (const file of files) {
      const displayName = file.replace(/\.blk$/, '');
      const li = document.createElement('li');
      li.textContent = displayName;
      li.addEventListener('click', () => selectDeviceItem(displayName, file, li));
      li.addEventListener('dblclick', () => { selectDeviceItem(displayName, file, li); loadDevice(); });
      deviceList.appendChild(li);
    }
    deviceStatus.textContent = '';
  } catch {
    deviceList.innerHTML = '<li class="empty-msg">Error reading device</li>';
    deviceStatus.textContent = 'Could not list files';
  }
}

function selectDeviceItem(displayName, filename, li) {
  deviceList.querySelectorAll('li').forEach(el => el.classList.remove('selected'));
  li.classList.add('selected');
  deviceSelected = filename;
  deviceNameInput.value = displayName;
  updateDeviceButtons();
}

function updateDeviceButtons() {
  const connected = checkConnected();
  deviceSaveBtn.disabled = !connected;
  deviceLoadBtn.disabled = !deviceSelected || !connected;
  deviceDeleteBtn.disabled = !deviceSelected || !connected;
}

async function saveDevice() {
  const name = deviceNameInput.value.trim();
  if (!name || !checkConnected()) return;
  const filename = name.endsWith('.blk') ? name : name + '.blk';
  const state = Blockly.serialization.workspaces.save(workspace);
  const json = JSON.stringify(state);

  deviceStatus.textContent = 'Saving...';
  deviceSaveBtn.disabled = true;
  try {
    await writeFile(json, filename);
    deviceNameInput.value = '';
    await refreshDeviceList();
  } catch {
    deviceStatus.textContent = 'Save failed';
  }
}

async function loadDevice() {
  if (!deviceSelected || !checkConnected()) return;
  deviceStatus.textContent = 'Loading...';
  try {
    const raw = await captureOutput(
      `f=open('${deviceSelected}','r')\nprint(f.read(),end='')\nf.close()`
    );
    const state = JSON.parse(raw.trim());
    Blockly.serialization.workspaces.load(state, workspace);
    deviceStatus.textContent = '';
  } catch {
    deviceStatus.textContent = 'Load failed';
  }
}

async function deleteDevice() {
  if (!deviceSelected || !checkConnected()) return;
  deviceStatus.textContent = 'Deleting...';
  try {
    await execCode(`import os\nos.remove('${deviceSelected}')`);
    await new Promise(r => setTimeout(r, 300));
    await refreshDeviceList();
  } catch {
    deviceStatus.textContent = 'Delete failed';
  }
}
