/**
 * Stationery Template Model
 *
 * Reusable stationery design templates — distinct from the produced `Stationery`
 * asset. A template is one of two kinds:
 *
 *  - `ai`     : generated as HTML+CSS with `{{placeholder}}` tokens. The HTML is
 *               an INTERNAL implementation detail and is never surfaced to end
 *               users; it is always rendered to an image before display.
 *  - `manual` : an uploaded image (PNG/JPG/WebP) with admin-defined editable
 *               placeholder regions (coordinates + type + styling) stored
 *               alongside the image. The original image is never mutated; user
 *               data is overlaid on it at generation time.
 *
 * Both kinds flow through the same guided approval + generation workflow.
 */

import mongoose, { Schema, Document } from 'mongoose';
import { STATIONERY_TYPE_VALUES, StationeryType } from './Stationery';

export type TemplateKind = 'ai' | 'manual';
export type TemplateSource = 'ai-generation' | 'admin-upload' | 'user-saved';
export type TemplateScope = 'company' | 'org' | 'global';
export type TemplateStatus = 'draft' | 'active' | 'archived';

// Editable field types shared by both kinds (drives the collect-data form).
export type PlaceholderType =
  | 'text'
  | 'textarea'
  | 'logo'
  | 'image'
  | 'qr'
  | 'signature'
  | 'date'
  | 'color';

export interface PlaceholderRegion {
  id: string;
  key: string; // matches a populate value key, e.g. 'companyName'
  label: string;
  type: PlaceholderType;
  required?: boolean;
  // Geometry on the base image, normalised to 0–100 (% of image box) so it
  // survives image rescaling.
  x: number;
  y: number;
  width: number;
  height: number;
  // Text styling (text/textarea/date types).
  fontSize?: number;
  fontFamily?: string;
  color?: string;
  fontWeight?: string;
  align?: 'left' | 'center' | 'right';
  lineHeight?: number;
  // Image/logo/qr/signature fit.
  fit?: 'contain' | 'cover';
  // Layer order — larger = drawn on top (Bring Forward / Send Backward).
  zIndex?: number;
}

export interface IStationeryTemplate extends Document {
  companyId?: string; // nullable → org/global template
  name: string;
  stationeryType: StationeryType;
  category?: string;
  kind: TemplateKind;
  // AI kind only (internal, never surfaced in UI).
  htmlTemplate?: string;
  backHtmlTemplate?: string;
  // Manual kind only.
  imageUrl?: string; // uploads path or dataURL — original, never mutated
  backImageUrl?: string;
  placeholders?: PlaceholderRegion[];
  backPlaceholders?: PlaceholderRegion[];
  // Both kinds — always an image (AI: client-rendered from HTML; manual: the upload).
  previewImageUrl?: string;
  backPreviewImageUrl?: string;
  dimensions?: {
    width: number;
    height: number;
    unit: 'mm' | 'in' | 'px';
  };
  source: TemplateSource;
  scope: TemplateScope;
  tags: string[];
  status: TemplateStatus;
  style?: string;
  description?: string;
  aiJobId?: string;
  createdAt: Date;
  updatedAt: Date;
}

const PlaceholderRegionSchema = new Schema<PlaceholderRegion>(
  {
    id: { type: String, required: true },
    key: { type: String, required: true },
    label: { type: String, required: true },
    type: {
      type: String,
      required: true,
      enum: ['text', 'textarea', 'logo', 'image', 'qr', 'signature', 'date', 'color'],
    },
    required: { type: Boolean, default: false },
    x: { type: Number, required: true },
    y: { type: Number, required: true },
    width: { type: Number, required: true },
    height: { type: Number, required: true },
    fontSize: Number,
    fontFamily: String,
    color: String,
    fontWeight: String,
    align: { type: String, enum: ['left', 'center', 'right'] },
    lineHeight: Number,
    fit: { type: String, enum: ['contain', 'cover'] },
    zIndex: { type: Number, default: 0 },
  },
  { _id: false }
);

const StationeryTemplateSchema = new Schema<IStationeryTemplate>(
  {
    companyId: { type: String, index: true }, // nullable for org/global
    name: {
      type: String,
      required: [true, 'Template name is required'],
      trim: true,
      maxlength: [120, 'Name cannot exceed 120 characters'],
    },
    stationeryType: {
      type: String,
      required: [true, 'Stationery type is required'],
      enum: STATIONERY_TYPE_VALUES,
    },
    category: String,
    kind: {
      type: String,
      required: [true, 'Template kind is required'],
      enum: ['ai', 'manual'],
    },
    // AI kind
    htmlTemplate: { type: String, maxlength: [250000, 'HTML template too large'] },
    backHtmlTemplate: { type: String, maxlength: [250000, 'Back HTML template too large'] },
    // Manual kind
    imageUrl: String,
    backImageUrl: String,
    placeholders: [PlaceholderRegionSchema],
    backPlaceholders: [PlaceholderRegionSchema],
    // Both
    previewImageUrl: String,
    backPreviewImageUrl: String,
    dimensions: {
      width: Number,
      height: Number,
      unit: { type: String, enum: ['mm', 'in', 'px'] },
    },
    source: {
      type: String,
      enum: ['ai-generation', 'admin-upload', 'user-saved'],
      default: 'user-saved',
    },
    scope: {
      type: String,
      enum: ['company', 'org', 'global'],
      default: 'company',
    },
    tags: { type: [String], default: [] },
    status: {
      type: String,
      enum: ['draft', 'active', 'archived'],
      default: 'active',
    },
    style: String,
    description: String,
    aiJobId: String,
  },
  { timestamps: true }
);

StationeryTemplateSchema.index({ companyId: 1, stationeryType: 1, status: 1 });
StationeryTemplateSchema.index({ scope: 1, stationeryType: 1 });
StationeryTemplateSchema.index({ kind: 1 });

export const StationeryTemplate = mongoose.model<IStationeryTemplate>(
  'StationeryTemplate',
  StationeryTemplateSchema
);