import { describe, expect, it } from 'vitest'
import type { ExamTemplateDetail } from '../../types/exam.types'
import { isUuid, pageForY, serializeCanvasShapes, shapesFromTemplate } from './model'

const template: ExamTemplateDetail = {
  id: 'tpl-1', title: 'Physics', subject: 'Physics', exam_id: null, exam_code: null, source_file_id: null, page_count: 1,
  institute_id: 'inst', teacher_id: 'teacher', status: 'draft', created_at: 'now', updated_at: 'now', questions: [], response_areas: [], boundaries: [], layout: [],
}

describe('exam setup canvas serialization', () => {
  it('pairs boundaries into a main question, attaches a Part, and attaches a response by containment', () => {
    const payload = serializeCanvasShapes(template, [
      { id: 'b-top', kind: 'boundary', x: 40, y: 100, w: 700, h: 8, label: 'Q1 start' },
      { id: 'b-bottom', kind: 'boundary', x: 40, y: 700, w: 700, h: 8, label: 'Q1 end' },
      { id: 'part-1', kind: 'part', x: 100, y: 180, w: 400, h: 220, label: 'Q1(a)', maxMarks: 3 },
      { id: 'resp-1', kind: 'response', x: 130, y: 250, w: 300, h: 90, responseForm: 'lines' },
    ])

    const main = payload.questions.find((q) => q.is_container)
    const part = payload.questions.find((q) => !q.is_container)
    expect(main?.label).toBe('Q1')
    expect(part?.parent_id).toBe(main?.id)
    expect(part?.bounds).toEqual({ x: 100, y: 180, w: 400, h: 220 })
    expect(payload.response_areas[0]).toMatchObject({ question_id: part?.id, kind: 'response', response_form: 'lines' })
    expect(payload.boundaries).toHaveLength(2)
    expect(payload.boundaries.every((b) => b.question_id === main?.id)).toBe(true)
    expect(payload.questions.every((q) => isUuid(q.id))).toBe(true)
    expect(payload.response_areas.every((r) => isUuid(r.id))).toBe(true)
    expect(payload.boundaries.every((b) => isUuid(b.id))).toBe(true)
  })

  it('maps shapes to the visible PDF page geometry rather than a fixed page height', () => {
    const pages = [
      { pageNumber: 1, x: 260, y: 0, w: 780, h: 1000 },
      { pageNumber: 2, x: 260, y: 1000, w: 780, h: 1200 },
    ]
    expect(pageForY(1050, pages)).toBe(2)
    const payload = serializeCanvasShapes(template, [
      { id: 'b-top', kind: 'boundary', x: 260, y: 1020, w: 700, h: 8, label: 'Q1 start' },
      { id: 'b-bottom', kind: 'boundary', x: 260, y: 1700, w: 700, h: 8, label: 'Q1 end' },
      { id: 'part-1', kind: 'part', x: 300, y: 1120, w: 300, h: 160, label: 'Q1(a)' },
      { id: 'resp-1', kind: 'response', x: 320, y: 1160, w: 240, h: 80 },
    ], pages)
    expect(payload.questions.find((q) => !q.is_container)?.page).toBe(2)
    expect(payload.boundaries.every((b) => b.page_index === 1)).toBe(true)
    expect(payload.boundaries.every((b) => b.bounds?.x === 260 && b.bounds?.w === 780)).toBe(true)
    expect(payload.response_areas[0].page).toBe(2)
  })

  it('round-trips saved Part geometry and all S4-9 region kinds from API detail', () => {
    const shapes = shapesFromTemplate({
      ...template,
      questions: [
        { id: 'q1', template_id: 'tpl-1', parent_id: null, label: 'Q1', order: 0, max_marks: 0, answer_type: null, mcq_options: null, mark_scheme: {}, is_container: true, spec_ref: null, source: 'manual', confirmed: true, confidence: null, derivation: null },
        { id: 'p1', template_id: 'tpl-1', parent_id: 'q1', label: 'Q1(a)', order: 0, max_marks: 2, answer_type: 'written', mcq_options: null, mark_scheme: {}, is_container: false, spec_ref: null, bounds: { x: 1, y: 2, w: 3, h: 4 }, page: 1, source: 'manual', confirmed: true, confidence: null, derivation: null },
      ],
      response_areas: [
        { id: 'r1', question_id: 'p1', template_id: 'tpl-1', page: 1, bounds: { x: 10, y: 20, w: 30, h: 40 }, kind: 'response', response_form: 'lines', source: 'manual', confirmed: true, confidence: null, derivation: null },
        { id: 'f1', question_id: 'p1', template_id: 'tpl-1', page: 1, bounds: { x: 11, y: 21, w: 31, h: 41 }, kind: 'furniture', response_form: null, source: 'manual', confirmed: true, confidence: null, derivation: null },
      ],
      boundaries: [{ id: 'b1', template_id: 'tpl-1', question_id: 'q1', label: 'Q1 start', page_index: 0, y: 100, bounds: { x: 0, y: 100, w: 700, h: 8 }, source: 'manual', confirmed: true, confidence: null, derivation: null }],
    })
    expect(shapes.map((s) => s.kind).sort()).toEqual(['boundary', 'furniture', 'part', 'response'])
    expect(shapes.find((s) => s.kind === 'boundary')).toMatchObject({ id: 'b1', x: 0, y: 100, w: 780, h: 8 })
    expect(shapes.find((s) => s.kind === 'part')).toMatchObject({ id: 'p1', x: 1, y: 2, w: 3, h: 4 })
  })
})
