/**
 * SDK Test Runner — Domain: projects
 */
(function () {
  'use strict';
  var T = window.SDKR;
  if (!T) return;

  T.registerDomain('projects', async function () {
    var tag = 'sdkr-' + Date.now();
    var projectId = null;
    var channelId = null;
    var noteId = null;

    // ── List ──

    await T.test('projects', 'list', 'sw.api.projects.list()', {
      sdk:      function () { return sw.api.projects.list(); },
      raw:      { method: 'GET', path: '/projects' },
      validate: function (r) { T.assert(Array.isArray(r), 'expected array'); }
    });

    // ── Create ──

    await T.test('projects', 'crud', 'sw.api.projects.create()', {
      sdk: function () {
        return sw.api.projects.create({ name: tag + '-proj', description: 'sdk test' });
      },
      raw: { method: 'POST', path: '/projects', body: { name: tag + '-proj', description: 'sdk test' } },
      validate: function (r) {
        T.assertShape(r, T.S.project, 'project');
        projectId = r.id;
        T.registerCleanup(function () { if (projectId) return T.safeDelete('/projects/' + projectId); });
      }
    });

    if (!projectId) return;

    // ── Get ──

    await T.test('projects', 'crud', 'sw.api.projects.get(id)', {
      sdk:      function () { return sw.api.projects.get(projectId); },
      raw:      { method: 'GET', path: '/projects/' + projectId },
      validate: function (r) {
        T.assertShape(r, T.S.project, 'project');
        T.assert(r.id === projectId, 'id mismatch');
      }
    });

    // ── Update ──

    await T.test('projects', 'crud', 'sw.api.projects.update(id, data)', {
      sdk:      function () { return sw.api.projects.update(projectId, { name: tag + '-proj-upd' }); },
      raw:      { method: 'PUT', path: '/projects/' + projectId, body: { name: tag + '-proj-upd' } },
      validate: function (r) {
        T.assertShape(r, T.S.project, 'project');
      }
    });

    // ── Channel association ──

    await T.test('projects', 'assoc', 'sw.api.projects.addChannel()', async function () {
      var ch = await T.raw.post('/channels', { title: tag + '-proj-ch', type: 'direct' });
      channelId = ch.id;
      T.registerCleanup(function () { if (channelId) return T.safeDelete('/channels/' + channelId); });
    });

    if (channelId) {
      await T.test('projects', 'assoc', 'sw.api.projects.addChannel(id, chId)', {
        sdk: function () { return sw.api.projects.addChannel(projectId, channelId, 0); },
        raw: { method: 'POST', path: '/projects/' + projectId + '/channels',
               body: { channel_id: channelId, position: 0 } },
        validate: function () { /* ok */ }
      });

      await T.test('projects', 'assoc', 'sw.api.projects.channels(id)', {
        sdk:      function () { return sw.api.projects.channels(projectId); },
        raw:      { method: 'GET', path: '/projects/' + projectId + '/channels' },
        validate: function (r) { T.assert(Array.isArray(r), 'expected array'); }
      });

      await T.test('projects', 'assoc', 'sw.api.projects.removeChannel()', {
        sdk: function () { return sw.api.projects.removeChannel(projectId, channelId); },
        raw: { method: 'DELETE', path: '/projects/' + projectId + '/channels/' + channelId },
        validate: function () { /* ok */ }
      });
    }

    // ── Note association ──

    await T.test('projects', 'assoc', 'create scratch note for project', async function () {
      var n = await T.raw.post('/notes', { title: tag + '-proj-note', content: 'test' });
      noteId = n.id;
      T.registerCleanup(function () { if (noteId) return T.safeDelete('/notes/' + noteId); });
    });

    if (noteId) {
      await T.test('projects', 'assoc', 'sw.api.projects.addNote()', {
        sdk: function () { return sw.api.projects.addNote(projectId, noteId); },
        raw: { method: 'POST', path: '/projects/' + projectId + '/notes',
               body: { note_id: noteId } },
        validate: function () { /* ok */ }
      });

      await T.test('projects', 'assoc', 'sw.api.projects.notes(id)', {
        sdk:      function () { return sw.api.projects.notes(projectId); },
        raw:      { method: 'GET', path: '/projects/' + projectId + '/notes' },
        validate: function (r) { T.assert(Array.isArray(r), 'expected array'); }
      });

      await T.test('projects', 'assoc', 'sw.api.projects.removeNote()', {
        sdk: function () { return sw.api.projects.removeNote(projectId, noteId); },
        raw: { method: 'DELETE', path: '/projects/' + projectId + '/notes/' + noteId },
        validate: function () { /* ok */ }
      });
    }

    // ── Files ──

    await T.test('projects', 'files', 'sw.api.projects.files(id)', {
      sdk:      function () { return sw.api.projects.files(projectId); },
      raw:      { method: 'GET', path: '/projects/' + projectId + '/files' },
      validate: function (r) { T.assert(typeof r === 'object' || Array.isArray(r), 'expected obj/arr'); }
    });

    // ── Delete ──

    await T.test('projects', 'crud', 'sw.api.projects.del(id)', {
      sdk:      function () { return sw.api.projects.del(projectId); },
      raw:      { method: 'DELETE', path: '/projects/' + projectId },
      validate: function () { projectId = null; }
    });
  });
})();
