/**
 * SOP Management Models
 *
 * SopCategory — hierarchical categories for organising SOPs
 * SOP — comprehensive standard operating procedure records
 */

import mongoose, { Schema, Document } from 'mongoose';

// ============================================
// SOP CATEGORY
// ============================================

export type SopCategoryStatus = 'active' | 'archived';

export interface ISopCategory extends Document {
  companyId: string;
  name: string;
  slug: string;
  description?: string;
  parentId?: string;
  icon?: string;
  colour?: string;
  order: number;
  sopCount: number;
  status: SopCategoryStatus;
  createdAt: Date;
  updatedAt: Date;
}

const SopCategorySchema = new Schema<ISopCategory>(
  {
    companyId: { type: String, required: [true, 'Company ID is required'] },
    name: { type: String, required: [true, 'Category name is required'], trim: true, maxlength: [100, 'Category name cannot exceed 100 characters'] },
    slug: { type: String, trim: true, lowercase: true },
    description: { type: String, trim: true },
    parentId: { type: String, index: true },
    icon: { type: String, trim: true },
    colour: { type: String, trim: true },
    order: { type: Number, default: 0 },
    sopCount: { type: Number, default: 0 },
    status: { type: String, enum: ['active', 'archived'], default: 'active' },
  },
  { timestamps: true }
);

SopCategorySchema.index({ companyId: 1, parentId: 1 });
SopCategorySchema.index({ companyId: 1, slug: 1 }, { unique: true });

SopCategorySchema.pre('save', function (this: ISopCategory) {
  if (this.isModified('name') || !this.slug) {
    this.slug = this.name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
  }
});

// ============================================
// SOP STEP SUB-SCHEMA
// ============================================

const SopStepSchema = new Schema(
  {
    id: { type: String, required: true },
    title: { type: String, required: true, maxlength: [200, 'Step title cannot exceed 200 characters'] },
    description: { type: String, default: '' },
    order: { type: Number, required: true },
    type: { type: String, enum: ['instruction', 'decision', 'check', 'note'], default: 'instruction' },
    assignee: { type: String },
    estimatedTime: { type: String },
    conditions: { type: [String], default: [] },
    checklist: { type: [String], default: [] },
    attachments: {
      type: [{
        url: { type: String, required: true },
        name: { type: String, required: true },
        type: { type: String, required: true },
        size: { type: Number },
      }],
      default: [],
    },
  },
  { _id: false }
);

// ============================================
// SOP VERSION SUB-SCHEMA
// ============================================

const SopVersionSchema = new Schema(
  {
    id: { type: String, required: true },
    version: { type: Number, required: true },
    changeSummary: { type: String, default: '' },
    modifiedBy: { type: String, default: '' },
    modifiedAt: { type: Date, default: Date.now },
    approvedBy: { type: String },
    approvedAt: { type: Date },
  },
  { _id: false }
);

// ============================================
// SOP
// ============================================

export type SopStatus = 'draft' | 'review' | 'approved' | 'published' | 'archived';
export type SopPriority = 'low' | 'medium' | 'high' | 'critical';
export type SopVisibility = 'private' | 'internal' | 'public';

export interface ISOP extends Document {
  companyId: string;
  sopId: string;
  title: string;
  slug: string;
  shortDescription?: string;
  detailedDescription?: string;
  objective?: string;
  scope?: string;
  categoryId?: string;
  department: string;
  tags: string[];
  status: SopStatus;
  priority: SopPriority;
  visibility: SopVisibility;
  owner?: string;
  reviewer?: string;
  approvalStatus: 'pending' | 'approved' | 'rejected' | 'changes_requested';
  approvedBy?: string;
  approvedAt?: Date;
  reviewNotes?: string;
  steps: any[];
  prerequisites: string[];
  relatedSopIds: string[];
  relatedCourseIds: string[];
  relatedFaqIds: string[];
  version: number;
  versionHistory: any[];
  templateId?: string;
  isTemplate: boolean;
  internalNotes?: string;
  metaTitle?: string;
  metaDescription?: string;
  viewCount: number;
  aiGenerated: boolean;
  createdAt: Date;
  updatedAt: Date;
}

const SopSchema = new Schema<ISOP>(
  {
    companyId: { type: String, required: [true, 'Company ID is required'] },
    sopId: { type: String, required: true, uppercase: true, match: /^SOP-\d+$/ },
    title: { type: String, required: [true, 'SOP title is required'], trim: true, maxlength: [300, 'Title cannot exceed 300 characters'] },
    slug: { type: String, trim: true, lowercase: true },
    shortDescription: { type: String, trim: true, maxlength: [500, 'Short description cannot exceed 500 characters'] },
    detailedDescription: { type: String, trim: true },
    objective: { type: String, trim: true },
    scope: { type: String, trim: true },
    categoryId: { type: String, index: true },
    department: {
      type: String,
      enum: ['engineering', 'marketing', 'sales', 'design', 'operations', 'hr', 'finance', 'customer-success', 'product', 'legal', 'other'],
      default: 'operations',
    },
    tags: { type: [String], default: [] },
    status: { type: String, enum: ['draft', 'review', 'approved', 'published', 'archived'], default: 'draft' },
    priority: { type: String, enum: ['low', 'medium', 'high', 'critical'], default: 'medium' },
    visibility: { type: String, enum: ['private', 'internal', 'public'], default: 'internal' },
    owner: { type: String },
    reviewer: { type: String },
    approvalStatus: { type: String, enum: ['pending', 'approved', 'rejected', 'changes_requested'], default: 'pending' },
    approvedBy: { type: String },
    approvedAt: { type: Date },
    reviewNotes: { type: String },
    steps: { type: [SopStepSchema] as any, default: [] },
    prerequisites: { type: [String], default: [] },
    relatedSopIds: { type: [String], default: [] },
    relatedCourseIds: { type: [String], default: [] },
    relatedFaqIds: { type: [String], default: [] },
    version: { type: Number, default: 1 },
    versionHistory: { type: [SopVersionSchema] as any, default: [] },
    templateId: { type: String },
    isTemplate: { type: Boolean, default: false },
    internalNotes: { type: String },
    metaTitle: { type: String },
    metaDescription: { type: String },
    viewCount: { type: Number, default: 0 },
    aiGenerated: { type: Boolean, default: false },
  },
  { timestamps: true }
);

SopSchema.index({ companyId: 1, status: 1 });
SopSchema.index({ companyId: 1, categoryId: 1 });
SopSchema.index({ companyId: 1, sopId: 1 }, { unique: true });
SopSchema.index({ companyId: 1, slug: 1 }, { unique: true });
SopSchema.index({ companyId: 1, department: 1 });
SopSchema.index({ title: 'text', shortDescription: 'text', detailedDescription: 'text' });

SopSchema.pre('save', function (this: ISOP) {
  if (this.isModified('title') || !this.slug) {
    this.slug = this.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
  }
});

export const SopCategory = mongoose.model<ISopCategory>('SopCategory', SopCategorySchema);
export const SOP = mongoose.model<ISOP>('SOP', SopSchema);