import { afterEach, beforeEach, describe, mock, test } from 'node:test';
import assert from 'node:assert/strict';

import db from '@/db/models';
import { CONTENT_CATALOG_SEED_PAYLOADS } from '@/db/seeders/content-catalog-data/content-catalog-seed-payloads';
import { seedDefaultContentForTenant } from '@/services/content_catalog_seed';

beforeEach(() => {
  mock.method(db.policy_documents, 'findOne', (async () => null) as typeof db.policy_documents.findOne);
  mock.method(db.policy_documents, 'create', (async (payload: Record<string, unknown>) =>
    payload) as typeof db.policy_documents.create);
});

afterEach(() => {
  mock.restoreAll();
});

describe('seedDefaultContentForTenant', () => {
  test('keeps dashboard sign of the week aligned with the seeded Help sign card', () => {
    const helpSign = CONTENT_CATALOG_SEED_PAYLOADS.signLanguageItems.find((sign) =>
      sign.word === 'Help'
    );

    assert.ok(helpSign);
    assert.equal(CONTENT_CATALOG_SEED_PAYLOADS.dashboardSignOfWeek.signId, helpSign.id);
    assert.match(CONTENT_CATALOG_SEED_PAYLOADS.dashboardSignOfWeek.weekOf, /^\d{4}-\d{2}-\d{2}$/);
    assert.equal(CONTENT_CATALOG_SEED_PAYLOADS.dashboardSignOfWeek.word, 'Help');
    assert.equal(CONTENT_CATALOG_SEED_PAYLOADS.dashboardSignOfWeek.description, helpSign.description);
    assert.equal(CONTENT_CATALOG_SEED_PAYLOADS.dashboardSignOfWeek.image, helpSign.image);
  });

  test('seeds dashboard content at organization scope', async () => {
    const createdRows: Array<Record<string, unknown>> = [];

    mock.method(db.content_catalog, 'findOne', (async () => null) as typeof db.content_catalog.findOne);
    mock.method(db.content_catalog, 'create', (async (payload: Record<string, unknown>) => {
      createdRows.push(payload);
      return payload;
    }) as typeof db.content_catalog.create);

    await seedDefaultContentForTenant({
      level: 'organization',
      organizationId: 'org-1',
    });

    const quoteRow = createdRows.find((row) =>
      row.content_type === 'dashboard-encouraging-quotes',
    );

    assert.ok(quoteRow);
    assert.equal(quoteRow.organizationId, 'org-1');
    assert.equal(quoteRow.schoolId, null);
    assert.equal(quoteRow.campusId, null);
    assert.equal(quoteRow.classId, null);
    assert.equal(quoteRow.active, true);
  });

  test('seeds classroom strategies only at organization scope', async () => {
    const createdRows: Array<Record<string, unknown>> = [];

    mock.method(db.content_catalog, 'findOne', (async () => null) as typeof db.content_catalog.findOne);
    mock.method(db.content_catalog, 'create', (async (payload: Record<string, unknown>) => {
      createdRows.push(payload);
      return payload;
    }) as typeof db.content_catalog.create);

    await seedDefaultContentForTenant({
      level: 'organization',
      organizationId: 'org-1',
    });
    await seedDefaultContentForTenant({
      level: 'school',
      organizationId: 'org-1',
      schoolId: 'school-1',
    });
    await seedDefaultContentForTenant({
      level: 'campus',
      organizationId: 'org-1',
      schoolId: 'school-1',
      campusId: 'campus-1',
    });

    const classroomRows = createdRows.filter((row) =>
      row.content_type === 'classroom-strategies',
    );

    assert.equal(classroomRows.length, 1);
    assert.equal(classroomRows[0]?.organizationId, 'org-1');
    assert.equal(classroomRows[0]?.schoolId, null);
    assert.equal(classroomRows[0]?.campusId, null);
    assert.equal(classroomRows[0]?.classId, null);
    assert.equal(classroomRows[0]?.active, true);
    assert.ok(Array.isArray(classroomRows[0]?.payload));
  });

  test('seeds safety quiz content only at organization scope', async () => {
    const createdRows: Array<Record<string, unknown>> = [];

    mock.method(db.content_catalog, 'findOne', (async () => null) as typeof db.content_catalog.findOne);
    mock.method(db.content_catalog, 'create', (async (payload: Record<string, unknown>) => {
      createdRows.push(payload);
      return payload;
    }) as typeof db.content_catalog.create);

    await seedDefaultContentForTenant({
      level: 'organization',
      organizationId: 'org-1',
    });
    await seedDefaultContentForTenant({
      level: 'school',
      organizationId: 'org-1',
      schoolId: 'school-1',
    });
    await seedDefaultContentForTenant({
      level: 'campus',
      organizationId: 'org-1',
      schoolId: 'school-1',
      campusId: 'campus-1',
    });

    const safetyQuizRows = createdRows.filter((row) =>
      row.content_type === 'safety-qbs-quiz',
    );

    assert.equal(safetyQuizRows.length, 1);
    assert.deepEqual(
      safetyQuizRows.map((row) => ({
        organizationId: row.organizationId,
        schoolId: row.schoolId,
        campusId: row.campusId,
      })),
      [
        { organizationId: 'org-1', schoolId: null, campusId: null },
      ],
    );
  });

  test('seeds Emotional Intelligence quizzes only at organization scope', async () => {
    const createdRows: Array<Record<string, unknown>> = [];

    mock.method(db.content_catalog, 'findOne', (async () => null) as typeof db.content_catalog.findOne);
    mock.method(db.content_catalog, 'create', (async (payload: Record<string, unknown>) => {
      createdRows.push(payload);
      return payload;
    }) as typeof db.content_catalog.create);

    await seedDefaultContentForTenant({
      level: 'organization',
      organizationId: 'org-1',
    });
    await seedDefaultContentForTenant({
      level: 'school',
      organizationId: 'org-1',
      schoolId: 'school-1',
    });
    await seedDefaultContentForTenant({
      level: 'campus',
      organizationId: 'org-1',
      schoolId: 'school-1',
      campusId: 'campus-1',
    });

    const quizRows = createdRows.filter((row) =>
      row.content_type === 'emotional-intelligence-assessment-questions' ||
      row.content_type === 'emotional-intelligence-personality-quiz',
    );

    assert.equal(quizRows.length, 2);
    assert.deepEqual(
      quizRows.map((row) => ({
        content_type: row.content_type,
        organizationId: row.organizationId,
        schoolId: row.schoolId,
        campusId: row.campusId,
      })).sort((left, right) => String(left.content_type).localeCompare(String(right.content_type))),
      [
        {
          content_type: 'emotional-intelligence-assessment-questions',
          organizationId: 'org-1',
          schoolId: null,
          campusId: null,
        },
        {
          content_type: 'emotional-intelligence-personality-quiz',
          organizationId: 'org-1',
          schoolId: null,
          campusId: null,
        },
      ],
    );
  });

  test('seeds Zones of Regulation content only at organization scope', async () => {
    const createdRows: Array<Record<string, unknown>> = [];

    mock.method(db.content_catalog, 'findOne', (async () => null) as typeof db.content_catalog.findOne);
    mock.method(db.content_catalog, 'create', (async (payload: Record<string, unknown>) => {
      createdRows.push(payload);
      return payload;
    }) as typeof db.content_catalog.create);

    await seedDefaultContentForTenant({
      level: 'organization',
      organizationId: 'org-1',
    });
    await seedDefaultContentForTenant({
      level: 'school',
      organizationId: 'org-1',
      schoolId: 'school-1',
    });
    await seedDefaultContentForTenant({
      level: 'campus',
      organizationId: 'org-1',
      schoolId: 'school-1',
      campusId: 'campus-1',
    });

    const zoneRows = createdRows.filter((row) =>
      row.content_type === 'regulation-zones' ||
      row.content_type === 'zones-of-regulation-page-content',
    );

    assert.equal(zoneRows.length, 2);
    assert.deepEqual(
      zoneRows.map((row) => ({
        content_type: row.content_type,
        organizationId: row.organizationId,
        schoolId: row.schoolId,
        campusId: row.campusId,
      })).sort((left, right) => String(left.content_type).localeCompare(String(right.content_type))),
      [
        {
          content_type: 'regulation-zones',
          organizationId: 'org-1',
          schoolId: null,
          campusId: null,
        },
        {
          content_type: 'zones-of-regulation-page-content',
          organizationId: 'org-1',
          schoolId: null,
          campusId: null,
        },
      ],
    );
    assert.ok(Array.isArray(zoneRows.find((row) => row.content_type === 'regulation-zones')?.payload));
  });

  test('seeds ESA funding content and acknowledgment document only at campus scope', async () => {
    const createdRows: Array<Record<string, unknown>> = [];
    const createdPolicies: Array<Record<string, unknown>> = [];

    mock.method(db.content_catalog, 'findOne', (async () => null) as typeof db.content_catalog.findOne);
    mock.method(db.content_catalog, 'create', (async (payload: Record<string, unknown>) => {
      createdRows.push(payload);
      return payload;
    }) as typeof db.content_catalog.create);
    mock.method(db.policy_documents, 'create', (async (payload: Record<string, unknown>) => {
      createdPolicies.push(payload);
      return payload;
    }) as typeof db.policy_documents.create);

    await seedDefaultContentForTenant({
      level: 'organization',
      organizationId: 'org-1',
    });
    await seedDefaultContentForTenant({
      level: 'school',
      organizationId: 'org-1',
      schoolId: 'school-1',
    });
    await seedDefaultContentForTenant({
      level: 'campus',
      organizationId: 'org-1',
      schoolId: 'school-1',
      campusId: 'campus-1',
    });

    const esaRows = createdRows.filter((row) =>
      row.content_type === 'esa-funding-content',
    );

    assert.equal(esaRows.length, 1);
    assert.equal(esaRows[0]?.organizationId, 'org-1');
    assert.equal(esaRows[0]?.schoolId, null);
    assert.equal(esaRows[0]?.campusId, 'campus-1');
    assert.equal(esaRows[0]?.classId, null);
    assert.equal(esaRows[0]?.active, true);
    assert.deepEqual(esaRows[0]?.payload, CONTENT_CATALOG_SEED_PAYLOADS.esaFundingContent);

    assert.equal(createdPolicies.length, 1);
    assert.deepEqual(createdPolicies[0], {
      title: 'ESA Funding Information',
      body: 'Staff must review the current ESA Funding Information page and acknowledge understanding of the campus guidance.',
      category: 'handbook_policy',
      tag: 'ESA Funding',
      author: null,
      steps: null,
      autism_considerations: null,
      version: 1,
      active: true,
      importHash: 'policy-doc-esa-funding-campus-1',
      organizationId: 'org-1',
      schoolId: null,
      campusId: 'campus-1',
      classId: null,
    });
  });
});
