/**
 * ICD Test Runner — CRUD: Team Workflows (v0.31.2)
 * Team-scoped workflow lifecycle via /teams/:teamId/workflows routes.
 * Tests ownership isolation: workflows created via team routes are
 * accessible only through team routes, and cross-team access is denied.
 */
(function () {
  'use strict';
  var T = window.ICD;
  if (!T) return;
  if (!T.crud) T.crud = {};

  T.crud.teamWorkflows = async function (testTag) {
    // Requires admin user (who is also team admin for fixtures.team)
    if (T.user.role !== 'admin') return;

    var team = T.fixtures && T.fixtures.team;
    if (!team) {
      await T.test('crud', 'team-workflows', 'SKIP — no fixture team', async function () {
        T.assert(false, 'fixtures.team not provisioned — run fixtures first');
      });
      return;
    }

    var teamId = team.id;
    var wfId = null;
    var wfSlug = testTag.toLowerCase().replace(/[^a-z0-9-]/g, '-') + '-twf';

    // ── Create via team route ──

    await T.test('crud', 'team-workflows', 'POST /teams/:teamId/workflows (create)', async function () {
      var d = await T.apiPost('/teams/' + teamId + '/workflows', {
        name: testTag + '-team-workflow',
        slug: wfSlug,
        description: 'Team workflow CRUD test',
        entry_mode: 'team_only'
      });
      T.assertShape(d, T.S.workflow, 'team workflow');
      T.assert(d.slug === wfSlug, 'slug mismatch: expected ' + wfSlug + ', got ' + d.slug);
      T.assert(d.team_id === teamId, 'team_id should be ' + teamId + ', got ' + d.team_id);
      wfId = d.id;
      T.registerCleanup(function () { if (wfId) return T.safeDelete('/workflows/' + wfId); });
    });

    if (!wfId) return;

    // ── Read via team route ──

    await T.test('crud', 'team-workflows', 'GET /teams/:teamId/workflows/:id (read)', async function () {
      var d = await T.apiGet('/teams/' + teamId + '/workflows/' + wfId);
      T.assertShape(d, T.S.workflow, 'team workflow');
      T.assert(d.id === wfId, 'id mismatch');
      T.assert(d.team_id === teamId, 'team_id mismatch');
    });

    // ── List via team route ──

    await T.test('crud', 'team-workflows', 'GET /teams/:teamId/workflows (list)', async function () {
      var d = await T.apiGet('/teams/' + teamId + '/workflows');
      T.assertHasKey(d, 'data', '/workflows');
      T.assert(Array.isArray(d.data), 'data should be array');
      var found = d.data.find(function (w) { return w.id === wfId; });
      T.assert(found, 'team workflow should appear in team list');
    });

    // ── Update via team route ──

    await T.test('crud', 'team-workflows', 'PATCH /teams/:teamId/workflows/:id (update)', async function () {
      var d = await T.apiPatch('/teams/' + teamId + '/workflows/' + wfId, {
        description: 'Updated by team admin',
        entry_mode: 'public_link'
      });
      T.assert(typeof d === 'object', 'expected object');
    });

    // ── Stage CRUD via team routes ──

    var stageIds = [];

    await T.test('crud', 'team-workflows', 'POST .../stages (create stage #1)', async function () {
      var d = await T.apiPost('/teams/' + teamId + '/workflows/' + wfId + '/stages', {
        name: 'Team Intake',
        ordinal: 0,
        history_mode: 'full',
        stage_mode: 'chat_only'
      });
      T.assertShape(d, T.S.workflowStage, 'stage');
      T.assert(d.name === 'Team Intake', 'name mismatch');
      stageIds.push(d.id);
    });

    await T.test('crud', 'team-workflows', 'POST .../stages (create stage #2)', async function () {
      var d = await T.apiPost('/teams/' + teamId + '/workflows/' + wfId + '/stages', {
        name: 'Team Review',
        ordinal: 1,
        history_mode: 'summary',
        stage_mode: 'review'
      });
      T.assertShape(d, T.S.workflowStage, 'stage');
      stageIds.push(d.id);
    });

    await T.test('crud', 'team-workflows', 'GET .../stages (list)', async function () {
      var d = await T.apiGet('/teams/' + teamId + '/workflows/' + wfId + '/stages');
      T.assertHasKey(d, 'data', '/stages');
      T.assert(d.data.length >= 2, 'expected at least 2 stages, got ' + d.data.length);
    });

    await T.test('crud', 'team-workflows', 'PUT .../stages/:sid (update)', async function () {
      var d = await T.apiPut('/teams/' + teamId + '/workflows/' + wfId + '/stages/' + stageIds[0], {
        name: 'Team Intake (updated)',
        ordinal: 0,
        history_mode: 'full',
        stage_mode: 'form_chat',
        form_template: { fields: [{ key: 'name', type: 'text', label: 'Name', required: true }] }
      });
      T.assert(typeof d === 'object', 'expected object');
    });

    if (stageIds.length >= 2) {
      await T.test('crud', 'team-workflows', 'PATCH .../stages/reorder', async function () {
        var reversed = stageIds.slice().reverse();
        var d = await T.apiPatch('/teams/' + teamId + '/workflows/' + wfId + '/stages/reorder', {
          ordered_ids: reversed
        });
        T.assert(typeof d === 'object', 'expected object');
      });
      // Restore order
      await T.apiPatch('/teams/' + teamId + '/workflows/' + wfId + '/stages/reorder', {
        ordered_ids: stageIds
      });
    }

    // ── Activate + Publish via team route ──

    var versionNum = null;

    await T.test('crud', 'team-workflows', 'PATCH activate + POST publish', async function () {
      await T.apiPatch('/teams/' + teamId + '/workflows/' + wfId, { is_active: true });
      var v = await T.apiPost('/teams/' + teamId + '/workflows/' + wfId + '/publish', {});
      T.assertShape(v, T.S.workflowVersion, 'version');
      T.assertHasKey(v, 'snapshot', 'version');
      versionNum = v.version_number;
    });

    await T.test('crud', 'team-workflows', 'GET .../versions/:v (read)', async function () {
      T.assert(versionNum !== null, 'no version number from publish');
      var d = await T.apiGet('/teams/' + teamId + '/workflows/' + wfId + '/versions/' + versionNum);
      T.assertShape(d, T.S.workflowVersion, 'version');
      T.assert(d.version_number === versionNum, 'version should be ' + versionNum);
    });

    // ── Ownership isolation: cross-team access denied ──

    await T.test('crud', 'team-workflows', 'GET /teams/fake-id/workflows/:id → 403', async function () {
      var d = await T.authFetch(await T.getAuthToken(), 'GET',
        '/teams/00000000-0000-0000-0000-000000000099/workflows/' + wfId, null);
      // Should be 403 (not a team member) or 404
      T.assert(d._status === 403 || d._status === 404,
        'cross-team access should be denied, got ' + d._status);
    });

    // ── Stage delete via team route ──

    if (stageIds.length >= 2) {
      await T.test('crud', 'team-workflows', 'DELETE .../stages/:sid', async function () {
        await T.apiDelete('/teams/' + teamId + '/workflows/' + wfId + '/stages/' + stageIds.pop());
      });
    }

    // ── Workflow delete via team route ──

    await T.test('crud', 'team-workflows', 'DELETE /teams/:teamId/workflows/:id', async function () {
      await T.apiDelete('/teams/' + teamId + '/workflows/' + wfId);
      wfId = null;
    });

  };
})();
