import { uid } from './util';

/**
 * Coordinate convention for annotations:
 *   All geometry is in UNROTATED page space, TOP-LEFT origin, y-down, PDF points.
 *   This matches CSS during editing; the exporter flips y once for pdf-lib and the
 *   page's /Rotate handles visual rotation of both original content and overlays.
 */

export type Pt = { x: number; y: number };
export type AnnoType =
  | 'text'
  | 'draw'
  | 'shape'
  | 'highlight'
  | 'underline'
  | 'strike'
  | 'note'
  | 'image'
  | 'signature'
  | 'link'
  | 'field';

export type ShapeKind = 'rect' | 'ellipse' | 'line' | 'arrow';
export type FieldKind = 'text' | 'checkbox' | 'dropdown' | 'radio';
export type TextAlign = 'left' | 'center' | 'right';

export interface BaseAnno {
  id: string;
  page: string; // PageState.id
  type: AnnoType;
  x: number;
  y: number;
  w: number;
  h: number;
  rotation?: number; // self-rotation in degrees, clockwise, about the box center
  flipH?: boolean; // mirror horizontally
  flipV?: boolean; // mirror vertically
  opacity?: number; // 0..1
  locked?: boolean;
}

export interface TextAnno extends BaseAnno {
  type: 'text';
  text: string;
  fontFamily: string;
  fontSize: number;
  color: string;
  bold?: boolean;
  italic?: boolean;
  underline?: boolean;
  align: TextAlign;
  bg?: string | null; // optional fill behind the text (white-out box)
}

export interface DrawAnno extends BaseAnno {
  type: 'draw';
  // points in page space (absolute), define the polyline
  points: Pt[];
  color: string;
  strokeWidth: number;
}

export interface ShapeAnno extends BaseAnno {
  type: 'shape';
  shape: ShapeKind;
  stroke: string;
  strokeWidth: number;
  fill?: string | null;
}

export interface MarkAnno extends BaseAnno {
  type: 'highlight' | 'underline' | 'strike';
  color: string;
  strokeWidth?: number; // line thickness for underline/strike (unused for highlight)
}

export interface NoteAnno extends BaseAnno {
  type: 'note';
  text: string;
  color: string;
}

export interface ImageAnno extends BaseAnno {
  type: 'image' | 'signature';
  dataUrl: string; // data: URL (png/jpeg)
  naturalW: number;
  naturalH: number;
}

export interface LinkAnno extends BaseAnno {
  type: 'link';
  url: string;
}

export type FieldStyle = 'box' | 'filled' | 'underline' | 'minimal';

export interface FieldAnno extends BaseAnno {
  type: 'field';
  field: FieldKind;
  name: string;
  value?: string | boolean;
  options?: string[]; // dropdown / radio
  fontSize?: number;
  required?: boolean;
  // appearance
  fieldStyle?: FieldStyle;
  textColor?: string;
  bgColor?: string | null;
  borderColor?: string;
  borderWidth?: number;
}

/** Default appearance for a newly-created form field of the given kind. */
export function defaultFieldStyle(): Pick<FieldAnno, 'fieldStyle' | 'textColor' | 'bgColor' | 'borderColor' | 'borderWidth' | 'fontSize'> {
  return { fieldStyle: 'box', textColor: '#12141b', bgColor: '#ffffff', borderColor: '#2f6bff', borderWidth: 1, fontSize: 12 };
}

export type Anno =
  | TextAnno
  | DrawAnno
  | ShapeAnno
  | MarkAnno
  | NoteAnno
  | ImageAnno
  | LinkAnno
  | FieldAnno;

export interface PageState {
  id: string;
  srcIndex: number; // index into the ORIGINAL loaded document
  width: number; // unrotated media width (points)
  height: number; // unrotated media height (points)
  baseRotation: number; // the original page /Rotate (0/90/180/270)
  rotation: number; // user-applied rotation delta (0/90/180/270)
  blank?: boolean; // an inserted blank page (no srcIndex content)
  deleted?: boolean;
}

export interface DocMeta {
  title?: string;
  author?: string;
  subject?: string;
  keywords?: string;
  creator?: string;
}

export interface YeetDoc {
  id: string;
  name: string;
  bytes: Uint8Array; // ORIGINAL pdf bytes — source of truth for page content
  pages: PageState[];
  annos: Anno[];
  meta: DocMeta;
  password?: string; // if the source was decrypted with one
}

export function newDoc(name: string, bytes: Uint8Array): YeetDoc {
  return { id: uid('doc_'), name, bytes, pages: [], annos: [], meta: {} };
}

/** Line thickness for an underline/strike mark; falls back to the old
 *  height-derived heuristic for marks created before `strokeWidth` existed. */
export function markThickness(a: MarkAnno): number {
  return a.strokeWidth ?? Math.max(1, a.h * 0.08);
}

/** The effective on-screen rotation of a page = base + user delta, normalized. */
export function effectiveRotation(p: PageState): number {
  return (((p.baseRotation + p.rotation) % 360) + 360) % 360;
}

/** Page dimensions as displayed (accounting for 90/270 swap). */
export function displaySize(p: PageState): { w: number; h: number } {
  const r = effectiveRotation(p);
  return r % 180 === 0 ? { w: p.width, h: p.height } : { w: p.height, h: p.width };
}

export const DEFAULT_TEXT: Omit<TextAnno, 'id' | 'page' | 'x' | 'y' | 'w' | 'h'> = {
  type: 'text',
  text: 'Text',
  fontFamily: 'Helvetica',
  fontSize: 16,
  color: '#12141b',
  align: 'left',
  bg: null,
};

/** The 14 standard PDF fonts we can embed without shipping font files. */
export const STANDARD_FONTS = [
  'Helvetica',
  'Times New Roman',
  'Courier',
] as const;
