
import React from 'react'
import { BaseBoxShapeTool, BaseBoxShapeUtil, HTMLContainer, T, TLBaseBoxShape, toDomPrecision } from '@tldraw/tldraw'
import type { ExamCanvasRegionKind, ExamCanvasShapeKind } from '../../../utils/exam-canvas/model'

export const SHAPE_TYPES = {
  boundary: 'exam-boundary',
  part: 'exam-part',
  response: 'exam-region-response',
  context: 'exam-region-context',
  question_number: 'exam-region-question-number',
  mark_area: 'exam-region-mark-area',
  reference: 'exam-region-reference',
  furniture: 'exam-region-furniture',
} as const

export type ExamCanvasTLShape = TLBaseBoxShape & {
  type: typeof SHAPE_TYPES[keyof typeof SHAPE_TYPES]
  props: {
    w: number
    h: number
    label: string
    kind: ExamCanvasShapeKind
    maxMarks?: number
    responseForm?: string
    contextType?: string
    questionId?: string | null
    domainId?: string
  }
}

const palette: Record<ExamCanvasShapeKind, { stroke: string; fill: string; dash?: string; label: string }> = {
  boundary: { stroke: '#ef4444', fill: 'rgba(239,68,68,0.06)', dash: '8 6', label: 'Boundary' },
  part: { stroke: '#f59e0b', fill: 'rgba(245,158,11,0.16)', label: 'Part' },
  response: { stroke: '#2563eb', fill: 'rgba(37,99,235,0.16)', label: 'Response' },
  context: { stroke: '#7c3aed', fill: 'rgba(124,58,237,0.14)', dash: '6 5', label: 'Context' },
  question_number: { stroke: '#0f766e', fill: 'rgba(15,118,110,0.14)', label: 'Question #' },
  mark_area: { stroke: '#16a34a', fill: 'rgba(22,163,74,0.14)', label: 'Marks' },
  reference: { stroke: '#0891b2', fill: 'rgba(8,145,178,0.14)', label: 'Reference' },
  furniture: { stroke: '#64748b', fill: 'rgba(100,116,139,0.12)', dash: '3 5', label: 'Furniture' },
}

function renderShape(shape: ExamCanvasTLShape) {
  const kind = shape.props.kind
  const p = palette[kind] ?? palette.response
  const isBoundary = kind === 'boundary'
  return (
    <HTMLContainer id={shape.id} style={{ width: toDomPrecision(shape.props.w), height: toDomPrecision(shape.props.h), pointerEvents: 'all' }}>
      <div style={{
        width: '100%', height: '100%', boxSizing: 'border-box', border: `${isBoundary ? 2 : 1.5}px solid ${p.stroke}`,
        borderStyle: p.dash ? 'dashed' : 'solid', borderRadius: isBoundary ? 999 : 10,
        background: isBoundary ? 'transparent' : p.fill, color: p.stroke, fontFamily: 'Inter, system-ui, sans-serif',
        display: 'flex', alignItems: isBoundary ? 'center' : 'flex-start', justifyContent: isBoundary ? 'center' : 'space-between',
        padding: isBoundary ? '0 8px' : 8, boxShadow: isBoundary ? 'none' : '0 10px 22px rgba(15,23,42,0.08)', overflow: 'hidden'
      }}>
        <span style={{ fontSize: 12, fontWeight: 800, textTransform: 'uppercase', letterSpacing: 0.6, background: 'rgba(255,255,255,0.84)', borderRadius: 999, padding: '2px 7px' }}>
          {shape.props.label || p.label}
        </span>
        {!isBoundary && shape.props.questionId && <span style={{ fontSize: 11, fontWeight: 700, opacity: .75 }}>Attached</span>}
      </div>
    </HTMLContainer>
  )
}

function defaultProps(kind: ExamCanvasShapeKind, w: number, h: number) {
  const p = palette[kind]
  return { w, h, label: p.label, kind, responseForm: kind === 'response' ? 'lines' : undefined, contextType: kind === 'context' ? 'generic' : undefined }
}

const sharedProps = { w: T.number, h: T.number, label: T.string, kind: T.string, maxMarks: T.optional(T.number), responseForm: T.optional(T.string), contextType: T.optional(T.string), questionId: T.optional(T.string), domainId: T.optional(T.string) }
const ind = (s: ExamCanvasTLShape) => <rect width={toDomPrecision(s.props.w)} height={toDomPrecision(s.props.h)} />
class BoundaryUtil extends BaseBoxShapeUtil<ExamCanvasTLShape> { static override type = SHAPE_TYPES.boundary; static override props = sharedProps; override getDefaultProps(){ return defaultProps('boundary', 680, 8) }; override component(shape: ExamCanvasTLShape){ return renderShape(shape) }; override indicator(shape: ExamCanvasTLShape){ return ind(shape) } }
class PartUtil extends BaseBoxShapeUtil<ExamCanvasTLShape> { static override type = SHAPE_TYPES.part; static override props = sharedProps; override getDefaultProps(){ return defaultProps('part', 420, 170) }; override component(shape: ExamCanvasTLShape){ return renderShape(shape) }; override indicator(shape: ExamCanvasTLShape){ return ind(shape) } }
function regionUtil(type: string, kind: ExamCanvasRegionKind, w = 360, h = 120) { return class extends BaseBoxShapeUtil<ExamCanvasTLShape> { static override type = type; static override props = sharedProps; override getDefaultProps(){ return defaultProps(kind, w, h) }; override component(shape: ExamCanvasTLShape){ return renderShape(shape) }; override indicator(shape: ExamCanvasTLShape){ return ind(shape) } } }

class BoundaryTool extends BaseBoxShapeTool { static override id = SHAPE_TYPES.boundary; static override initial = 'pointing'; shapeType = SHAPE_TYPES.boundary }
class PartTool extends BaseBoxShapeTool { static override id = SHAPE_TYPES.part; static override initial = 'pointing'; shapeType = SHAPE_TYPES.part }
class ResponseTool extends BaseBoxShapeTool { static override id = SHAPE_TYPES.response; static override initial = 'pointing'; shapeType = SHAPE_TYPES.response }
class ContextTool extends BaseBoxShapeTool { static override id = SHAPE_TYPES.context; static override initial = 'pointing'; shapeType = SHAPE_TYPES.context }
class QuestionNumberTool extends BaseBoxShapeTool { static override id = SHAPE_TYPES.question_number; static override initial = 'pointing'; shapeType = SHAPE_TYPES.question_number }
class MarkAreaTool extends BaseBoxShapeTool { static override id = SHAPE_TYPES.mark_area; static override initial = 'pointing'; shapeType = SHAPE_TYPES.mark_area }
class ReferenceTool extends BaseBoxShapeTool { static override id = SHAPE_TYPES.reference; static override initial = 'pointing'; shapeType = SHAPE_TYPES.reference }
class FurnitureTool extends BaseBoxShapeTool { static override id = SHAPE_TYPES.furniture; static override initial = 'pointing'; shapeType = SHAPE_TYPES.furniture }

export const examCanvasShapeUtils = [BoundaryUtil, PartUtil, regionUtil(SHAPE_TYPES.response, 'response'), regionUtil(SHAPE_TYPES.context, 'context'), regionUtil(SHAPE_TYPES.question_number, 'question_number', 170, 80), regionUtil(SHAPE_TYPES.mark_area, 'mark_area', 170, 80), regionUtil(SHAPE_TYPES.reference, 'reference'), regionUtil(SHAPE_TYPES.furniture, 'furniture')] as const
export const examCanvasTools = [BoundaryTool, PartTool, ResponseTool, ContextTool, QuestionNumberTool, MarkAreaTool, ReferenceTool, FurnitureTool] as const

export function shapeTypeToKind(type: string): ExamCanvasShapeKind | null {
  const entry = Object.entries(SHAPE_TYPES).find(([, v]) => v === type)
  return (entry?.[0] as ExamCanvasShapeKind | undefined) ?? null
}
