/**
 * Book Management Models
 *
 * BookCategory — hierarchical categories for organising books
 * Book — comprehensive book records with enterprise mapping, SEO, and AI fields
 * BookChapter — chapter structure within a book
 * BookSection — section/subchapter structure within a chapter
 * BookContentBlock — content blocks within sections for rich content
 */

import mongoose, { Schema, Document } from 'mongoose';

// ============================================
// TYPE DEFINITIONS
// ============================================

export type BookCategoryStatus = 'active' | 'archived';

export type PublicationType =
  | 'book'
  | 'ebook'
  | 'whitepaper'
  | 'research-paper'
  | 'report'
  | 'magazine'
  | 'journal-article'
  | 'case-study'
  | 'guide'
  | 'handbook'
  | 'manual'
  | 'sop-book'
  | 'training-manual'
  | 'marketing-guide'
  | 'product-guide'
  | 'onboarding-book'
  | 'other';

export type PublicationStatus =
  | 'idea'
  | 'outline'
  | 'draft'
  | 'review'
  | 'editing'
  | 'proofreading'
  | 'final'
  | 'published'
  | 'archived';

export type PublicationFormat =
  | 'print'
  | 'ebook'
  | 'audiobook'
  | 'pdf'
  | 'web'
  | 'print-ebook'
  | 'print-audio'
  | 'ebook-audio'
  | 'all-formats';

export type DistributionChannel =
  | 'amazon'
  | 'apple-books'
  | 'google-books'
  | 'kobo'
  | 'barnes-noble'
  | 'smashwords'
  | 'gumroad'
  | 'website'
  | 'linkedin'
  | 'medium'
  | 'substack'
  | 'researchgate'
  | 'ssrn'
  | 'other';

export type BookChapterStatus = 'outline' | 'draft' | 'review' | 'final' | 'published';

export type BookSectionType =
  | 'introduction'
  | 'content'
  | 'case-study'
  | 'example'
  | 'exercise'
  | 'summary'
  | 'appendix'
  | 'references'
  | 'footnotes';

export type BookSectionStatus = 'outline' | 'draft' | 'review' | 'final';

export type ContentBlockType =
  | 'paragraph'
  | 'heading'
  | 'subheading'
  | 'quote'
  | 'code'
  | 'list'
  | 'numbered-list'
  | 'image'
  | 'video'
  | 'audio'
  | 'embed'
  | 'callout'
  | 'warning'
  | 'tip'
  | 'note'
  | 'table'
  | 'chart'
  | 'equation'
  | 'exercise'
  | 'quiz'
  | 'reflection';

export type ApprovalStatus = 'pending' | 'approved' | 'rejected' | 'changes_requested';

// ============================================
// BOOK CATEGORY
// ============================================

export interface IBookCategory extends Document {
  companyId: string;
  name: string;
  slug: string;
  description?: string;
  parentId?: string;
  icon?: string;
  colour?: string;
  order: number;
  bookCount: number;
  status: BookCategoryStatus;
  createdAt: Date;
  updatedAt: Date;
}

const BookCategorySchema = new Schema<IBookCategory>(
  {
    companyId: {
      type: String,
      required: [true, 'Company ID is required'],
      index: true,
    },
    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,
    },
    bookCount: {
      type: Number,
      default: 0,
    },
    status: {
      type: String,
      enum: ['active', 'archived'],
      default: 'active',
    },
  },
  { timestamps: true }
);

BookCategorySchema.index({ companyId: 1, parentId: 1 });
BookCategorySchema.index({ companyId: 1, slug: 1 }, { unique: true });

BookCategorySchema.pre('save', function (this: IBookCategory) {
  if (this.isModified('name') || !this.slug) {
    this.slug = this.name
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-|-$/g, '');
  }
});

export const BookCategory = mongoose.model<IBookCategory>('BookCategory', BookCategorySchema);

// ============================================
// SUB-SCHEMAS FOR BOOK
// ============================================

export interface IAuthor {
  id: string;
  name: string;
  role?: 'author' | 'co-author' | 'contributor' | 'editor';
  bio?: string;
  photo?: string;
  linkedin?: string;
  twitter?: string;
  website?: string;
}

const AuthorSchema = new Schema<IAuthor>(
  {
    id: { type: String, required: true },
    name: { type: String, required: true },
    role: {
      type: String,
      enum: ['author', 'co-author', 'contributor', 'editor'],
      default: 'author',
    },
    bio: String,
    photo: String,
    linkedin: String,
    twitter: String,
    website: String,
  },
  { _id: false }
);

export interface IPublicationMetric {
  date: Date;
  downloads?: number;
  views?: number;
  sales?: number;
  revenue?: number;
  currency?: string;
  reviews?: number;
  averageRating?: number;
}

const PublicationMetricSchema = new Schema<IPublicationMetric>(
  {
    date: { type: Date, required: true },
    downloads: Number,
    views: Number,
    sales: Number,
    revenue: Number,
    currency: { type: String, default: 'USD' },
    reviews: Number,
    averageRating: Number,
  },
  { _id: false }
);

export interface IDistributionLink {
  channel: DistributionChannel;
  url: string;
  isActive: boolean;
  publishedAt?: Date;
}

const DistributionLinkSchema = new Schema<IDistributionLink>(
  {
    channel: {
      type: String,
      enum: ['amazon', 'apple-books', 'google-books', 'kobo', 'barnes-noble', 'smashwords', 'gumroad', 'website', 'linkedin', 'medium', 'substack', 'researchgate', 'ssrn', 'other'],
      required: true,
    },
    url: { type: String, required: true },
    isActive: { type: Boolean, default: true },
    publishedAt: Date,
  },
  { _id: false }
);

export interface ILaunchPromotion {
  id: string;
  type: 'pre-order' | 'launch-discount' | 'bonus-content' | 'webinar' | 'email-campaign' | 'social-campaign';
  title: string;
  description?: string;
  startDate?: Date;
  endDate?: Date;
  discountPercent?: number;
  bonusContent?: string;
  campaignUrl?: string;
  status: 'planned' | 'active' | 'completed';
}

const LaunchPromotionSchema = new Schema<ILaunchPromotion>(
  {
    id: { type: String, required: true },
    type: {
      type: String,
      enum: ['pre-order', 'launch-discount', 'bonus-content', 'webinar', 'email-campaign', 'social-campaign'],
      required: true,
    },
    title: { type: String, required: true },
    description: String,
    startDate: Date,
    endDate: Date,
    discountPercent: Number,
    bonusContent: String,
    campaignUrl: String,
    status: {
      type: String,
      enum: ['planned', 'active', 'completed'],
      default: 'planned',
    },
  },
  { _id: false }
);

export interface IBookVersion {
  id: string;
  version: number;
  changeSummary: string;
  modifiedBy: string;
  modifiedAt: Date;
  approvedBy?: string;
  approvedAt?: Date;
}

const BookVersionSchema = new Schema<IBookVersion>(
  {
    id: { type: String, required: true },
    version: { type: Number, required: true },
    changeSummary: { type: String, required: true },
    modifiedBy: { type: String, required: true },
    modifiedAt: { type: Date, default: Date.now },
    approvedBy: String,
    approvedAt: Date,
  },
  { _id: false }
);

// ============================================
// BOOK
// ============================================

export interface IBook extends Document {
  // A. Core Information
  title: string;
  slug: string;
  subtitle?: string;
  description?: string;
  longDescription?: string;
  executiveSummary?: string;
  type: PublicationType;
  status: PublicationStatus;

  // B. Authors
  authors: IAuthor[];

  // C. Publication Details
  isbn?: string;
  isbnEbook?: string;
  isbnAudiobook?: string;
  publisher?: string;
  publishedDate?: Date;
  edition?: string;
  version: number;
  language: string;
  contentLanguage?: string; // Language used for AI-generated content (English, Hindi, Marathi) — separate from publication language

  // D. Format & Specifications
  formats: PublicationFormat[];
  pageCount?: number;
  wordCount?: number;
  estimatedReadTime?: number;
  fileFormats?: string[];

  // E. Categorisation
  categoryId?: string;
  keywords: string[];
  tags: string[];
  targetAudience?: string;

  // F. Pricing
  pricePrint?: number;
  priceEbook?: number;
  priceAudiobook?: number;
  currency: string;

  // G. Media & Assets
  coverImageUrl?: string;
  coverThumbnailUrl?: string;
  bannerImageUrl?: string;
  videoUrl?: string;
  sampleChapterUrl?: string;
  fullDocumentUrl?: string;
  audioFileUrl?: string;

  // H. Distribution
  distributionLinks: IDistributionLink[];

  // I. Analytics
  metrics: IPublicationMetric[];
  totalDownloads: number;
  totalViews: number;
  totalSales: number;
  totalRevenue: number;

  // J. Launch & Promotions
  launchDate?: Date;
  launchPromotions: ILaunchPromotion[];
  preOrderUrl?: string;
  launchWebinarUrl?: string;

  // K. Reviews & Ratings
  averageRating?: number;
  totalReviews: number;
  featuredReviews: string[];

  // L. SEO
  seoTitle?: string;
  seoDescription?: string;
  seoKeywords: string[];

  // M. Version & Approval
  versionHistory: IBookVersion[];
  approvedBy?: string;
  approvedAt?: Date;
  reviewNotes?: string;
  approvalStatus: ApprovalStatus;

  // N. AI Generation
  aiGenerated: boolean;
  aiPrompt?: string;
  aiModel?: string;
  outlinePrompt?: string;
  chapterPrompts: string[];
  /**
   * The wizard's layout & formatting choices (chapter/lesson layout, callouts,
   * visual identity, AI instructions). Stored so re-opening the book in the Edit
   * wizard regenerates with the same layout instead of falling back to defaults.
   * Mixed because the shape is owned by the wizard's AI Prompt step.
   */
  generationConfig?: Record<string, any>;

  // O. Generated Content (AI-generated book content)
  generatedContent?: {
    status: 'none' | 'generating' | 'completed' | 'failed';
    jobId?: string;
    generatedAt?: Date;
    updatedAt?: Date;
    error?: string;
    chapters?: Array<{ content: string; status: string }>;
    sections?: Record<string, any>;
  };

  // P. Cross-Module References
  linkedProductIds: string[];
  linkedServiceIds: string[];
  linkedSopIds: string[];
  linkedCourseIds: string[];
  linkedFaqIds: string[];
  linkedCaseStudyIds: string[];
  linkedFounderIds: string[];
  linkedEmployeeIds: string[];

  // Q. Stats
  chapterCount: number;
  isFeatured: boolean;
  internalNotes?: string;

  // R. Company Reference
  companyId: string;

  // Timestamps
  createdAt: Date;
  updatedAt: Date;
}

const BookSchema = new Schema<IBook>(
  {
    // A. Core Information
    title: {
      type: String,
      required: [true, 'Title is required'],
      trim: true,
      maxlength: [300, 'Title cannot exceed 300 characters'],
    },
    slug: {
      type: String,
      trim: true,
      lowercase: true,
    },
    subtitle: { type: String, trim: true },
    description: { type: String, trim: true },
    longDescription: { type: String, trim: true },
    executiveSummary: { type: String, trim: true },
    type: {
      type: String,
      enum: ['book', 'ebook', 'whitepaper', 'research-paper', 'report', 'magazine', 'journal-article', 'case-study', 'guide', 'handbook', 'manual', 'sop-book', 'training-manual', 'marketing-guide', 'product-guide', 'onboarding-book', 'other'],
      required: [true, 'Publication type is required'],
      default: 'book',
    },
    status: {
      type: String,
      enum: ['idea', 'outline', 'draft', 'review', 'editing', 'proofreading', 'final', 'published', 'archived'],
      default: 'idea',
    },

    // B. Authors
    authors: [AuthorSchema],

    // C. Publication Details
    isbn: String,
    isbnEbook: String,
    isbnAudiobook: String,
    publisher: String,
    publishedDate: Date,
    edition: String,
    version: { type: Number, default: 1 },
    language: { type: String, default: 'English' },
    contentLanguage: { type: String, default: 'English' }, // Language used for AI-generated content (English, Hindi, Marathi) — separate from publication language

    // D. Format & Specifications
    formats: [{
      type: String,
      enum: ['print', 'ebook', 'audiobook', 'pdf', 'web', 'print-ebook', 'print-audio', 'ebook-audio', 'all-formats'],
    }],
    pageCount: Number,
    wordCount: Number,
    estimatedReadTime: Number,
    fileFormats: [String],

    // E. Categorisation
    categoryId: {
      type: String,
      index: true,
    },
    keywords: [String],
    tags: [String],
    targetAudience: String,

    // F. Pricing
    pricePrint: Number,
    priceEbook: Number,
    priceAudiobook: Number,
    currency: { type: String, default: 'USD' },

    // G. Media & Assets
    coverImageUrl: String,
    coverThumbnailUrl: String,
    bannerImageUrl: String,
    videoUrl: String,
    sampleChapterUrl: String,
    fullDocumentUrl: String,
    audioFileUrl: String,

    // H. Distribution
    distributionLinks: [DistributionLinkSchema],

    // I. Analytics
    metrics: [PublicationMetricSchema],
    totalDownloads: { type: Number, default: 0 },
    totalViews: { type: Number, default: 0 },
    totalSales: { type: Number, default: 0 },
    totalRevenue: { type: Number, default: 0 },

    // J. Launch & Promotions
    launchDate: Date,
    launchPromotions: [LaunchPromotionSchema],
    preOrderUrl: String,
    launchWebinarUrl: String,

    // K. Reviews & Ratings
    averageRating: Number,
    totalReviews: { type: Number, default: 0 },
    featuredReviews: [String],

    // L. SEO
    seoTitle: {
      type: String,
      trim: true,
      maxlength: [60, 'SEO title cannot exceed 60 characters'],
    },
    seoDescription: {
      type: String,
      trim: true,
      maxlength: [160, 'SEO description cannot exceed 160 characters'],
    },
    seoKeywords: [String],

    // M. Version & Approval
    versionHistory: [BookVersionSchema],
    approvedBy: String,
    approvedAt: Date,
    reviewNotes: String,
    approvalStatus: {
      type: String,
      enum: ['pending', 'approved', 'rejected', 'changes_requested'],
      default: 'pending',
    },

    // N. AI Generation
    aiGenerated: { type: Boolean, default: false },
    aiPrompt: String,
    aiModel: String,
    outlinePrompt: String,
    chapterPrompts: [String],
    generationConfig: { type: Schema.Types.Mixed },

    // O. Generated Content (AI-generated book content)
    generatedContent: {
      status: { type: String, enum: ['none', 'generating', 'completed', 'failed'], default: 'none' },
      jobId: String,
      generatedAt: Date,
      updatedAt: Date,
      error: String,
      chapters: [{ content: String, status: String }],
      sections: { type: Schema.Types.Mixed, default: {} },
    },

    // P. Cross-Module References
    linkedProductIds: [String],
    linkedServiceIds: [String],
    linkedSopIds: [String],
    linkedCourseIds: [String],
    linkedFaqIds: [String],
    linkedCaseStudyIds: [String],
    linkedFounderIds: [String],
    linkedEmployeeIds: [String],

    // Q. Stats
    chapterCount: { type: Number, default: 0 },
    isFeatured: { type: Boolean, default: false },
    internalNotes: String,

    // R. Company Reference
    companyId: {
      type: String,
      required: [true, 'Company ID is required'],
      index: true,
    },
  },
  { timestamps: true }
);

// ============================================
// BOOK INDEXES
// ============================================

BookSchema.index({ companyId: 1, status: 1 });
BookSchema.index({ companyId: 1, categoryId: 1 });
BookSchema.index({ companyId: 1, type: 1 });
BookSchema.index({ companyId: 1, slug: 1 }, { unique: true });
BookSchema.index({ companyId: 1, publishedDate: -1 });
BookSchema.index({ companyId: 1, 'authors.id': 1 });
BookSchema.index({ title: 'text', description: 'text', longDescription: 'text' });

BookSchema.pre('save', function (this: IBook) {
  if (this.isModified('title') || !this.slug) {
    this.slug = this.title
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-|-$/g, '');
  }
});

export const Book = mongoose.model<IBook>('Book', BookSchema);

// ============================================
// BOOK CHAPTER
// ============================================

export interface IBookChapter extends Document {
  companyId: string;
  bookId: string;
  title: string;
  slug: string;
  description?: string;
  order: number;
  status: BookChapterStatus;

  // Content
  content?: string; // Generated chapter content
  wordCount?: number;
  estimatedReadTime?: number;

  // Learning
  learningObjectives: string[];
  keyTakeaways: string[];

  // Media
  thumbnail?: string;
  videoUrls: string[];

  // AI Generation
  aiGenerated: boolean;
  aiPrompt?: string;

  // Internal
  internalNotes?: string;

  // Stats
  sectionCount: number;

  createdAt: Date;
  updatedAt: Date;
}

const BookChapterSchema = new Schema<IBookChapter>(
  {
    companyId: {
      type: String,
      required: [true, 'Company ID is required'],
      index: true,
    },
    bookId: {
      type: String,
      required: [true, 'Book ID is required'],
      index: true,
    },
    title: {
      type: String,
      required: [true, 'Chapter title is required'],
      trim: true,
      maxlength: [200, 'Chapter title cannot exceed 200 characters'],
    },
    slug: {
      type: String,
      trim: true,
      lowercase: true,
    },
    description: {
      type: String,
      trim: true,
    },
    order: {
      type: Number,
      default: 0,
    },
    status: {
      type: String,
      enum: ['outline', 'draft', 'review', 'final', 'published'],
      default: 'outline',
    },

    // Content
    content: {
      type: String,
      default: '',
    },
    wordCount: Number,
    estimatedReadTime: Number,

    // Learning
    learningObjectives: [String],
    keyTakeaways: [String],

    // Media
    thumbnail: String,
    videoUrls: [String],

    // AI Generation
    aiGenerated: {
      type: Boolean,
      default: false,
    },
    aiPrompt: String,

    // Internal
    internalNotes: String,

    // Stats
    sectionCount: {
      type: Number,
      default: 0,
    },
  },
  { timestamps: true }
);

BookChapterSchema.index({ companyId: 1, bookId: 1 });
BookChapterSchema.index({ bookId: 1, order: 1 });

BookChapterSchema.pre('save', function (this: IBookChapter) {
  if (this.isModified('title') || !this.slug) {
    this.slug = this.title
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-|-$/g, '');
  }
});

export const BookChapter = mongoose.model<IBookChapter>('BookChapter', BookChapterSchema);

// ============================================
// BOOK SECTION
// ============================================

export interface ISectionAttachment {
  url: string;
  name: string;
  type: string;
  size?: number;
}

const SectionAttachmentSchema = new Schema<ISectionAttachment>(
  {
    url: { type: String, required: true },
    name: { type: String, required: true },
    type: { type: String, required: true },
    size: { type: Number },
  },
  { _id: false }
);

export interface IBookSection extends Document {
  companyId: string;
  bookId: string;
  chapterId: string;
  title: string;
  slug: string;
  type: BookSectionType;
  status: BookSectionStatus;
  order: number;

  // Content
  content?: string;
  wordCount?: number;

  // Rich Content
  keyPoints: string[];
  examples: string[];
  quotes: string[];

  // Media Attachments
  attachments: ISectionAttachment[];
  images: string[];

  // AI Generation
  aiGenerated: boolean;
  aiPrompt?: string;

  createdAt: Date;
  updatedAt: Date;
}

const BookSectionSchema = new Schema<IBookSection>(
  {
    companyId: {
      type: String,
      required: [true, 'Company ID is required'],
      index: true,
    },
    bookId: {
      type: String,
      required: [true, 'Book ID is required'],
      index: true,
    },
    chapterId: {
      type: String,
      required: [true, 'Chapter ID is required'],
      index: true,
    },
    title: {
      type: String,
      required: [true, 'Section title is required'],
      trim: true,
      maxlength: [200, 'Section title cannot exceed 200 characters'],
    },
    slug: {
      type: String,
      trim: true,
      lowercase: true,
    },
    type: {
      type: String,
      enum: ['introduction', 'content', 'case-study', 'example', 'exercise', 'summary', 'appendix', 'references', 'footnotes'],
      default: 'content',
    },
    status: {
      type: String,
      enum: ['outline', 'draft', 'review', 'final'],
      default: 'outline',
    },
    order: {
      type: Number,
      default: 0,
    },

    // Content
    content: {
      type: String,
      trim: true,
    },
    wordCount: Number,

    // Rich Content
    keyPoints: [String],
    examples: [String],
    quotes: [String],

    // Media Attachments
    attachments: [SectionAttachmentSchema],
    images: [String],

    // AI Generation
    aiGenerated: {
      type: Boolean,
      default: false,
    },
    aiPrompt: String,
  },
  { timestamps: true }
);

BookSectionSchema.index({ companyId: 1, bookId: 1 });
BookSectionSchema.index({ companyId: 1, chapterId: 1 });
BookSectionSchema.index({ chapterId: 1, order: 1 });

BookSectionSchema.pre('save', function (this: IBookSection) {
  if (this.isModified('title') || !this.slug) {
    this.slug = this.title
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-|-$/g, '');
  }
});

export const BookSection = mongoose.model<IBookSection>('BookSection', BookSectionSchema);

// ============================================
// BOOK CONTENT BLOCK
// ============================================

export interface IContentBlockMetadata {
  caption?: string;
  alt?: string;
  source?: string;
  language?: string;
  style?: string;
}

const ContentBlockMetadataSchema = new Schema<IContentBlockMetadata>(
  {
    caption: String,
    alt: String,
    source: String,
    language: String,
    style: String,
  },
  { _id: false }
);

export interface IContentBlockFormatting {
  alignment?: 'left' | 'center' | 'right' | 'justify';
  colour?: string;
  fontSize?: string;
}

const ContentBlockFormattingSchema = new Schema<IContentBlockFormatting>(
  {
    alignment: {
      type: String,
      enum: ['left', 'center', 'right', 'justify'],
    },
    colour: String,
    fontSize: String,
  },
  { _id: false }
);

export interface IBookContentBlock extends Document {
  companyId: string;
  bookId: string;
  chapterId: string;
  sectionId: string;
  order: number;
  type: ContentBlockType;

  // Content
  content: string;
  metadata?: IContentBlockMetadata;
  formatting?: IContentBlockFormatting;

  createdAt: Date;
  updatedAt: Date;
}

const BookContentBlockSchema = new Schema<IBookContentBlock>(
  {
    companyId: {
      type: String,
      required: [true, 'Company ID is required'],
      index: true,
    },
    bookId: {
      type: String,
      required: [true, 'Book ID is required'],
      index: true,
    },
    chapterId: {
      type: String,
      required: [true, 'Chapter ID is required'],
      index: true,
    },
    sectionId: {
      type: String,
      required: [true, 'Section ID is required'],
      index: true,
    },
    order: {
      type: Number,
      default: 0,
    },
    type: {
      type: String,
      enum: ['paragraph', 'heading', 'subheading', 'quote', 'code', 'list', 'numbered-list', 'image', 'video', 'audio', 'embed', 'callout', 'warning', 'tip', 'note', 'table', 'chart', 'equation', 'exercise', 'quiz', 'reflection'],
      required: [true, 'Content block type is required'],
      default: 'paragraph',
    },

    // Content
    content: {
      type: String,
      required: [true, 'Content is required'],
    },
    metadata: ContentBlockMetadataSchema,
    formatting: ContentBlockFormattingSchema,
  },
  { timestamps: true }
);

BookContentBlockSchema.index({ companyId: 1, bookId: 1 });
BookContentBlockSchema.index({ companyId: 1, sectionId: 1 });
BookContentBlockSchema.index({ sectionId: 1, order: 1 });

export const BookContentBlock = mongoose.model<IBookContentBlock>('BookContentBlock', BookContentBlockSchema);