import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  ManyToOne,
  JoinColumn,
  ValueTransformer,
  OneToMany,
} from 'typeorm';

class ArrayTransformer implements ValueTransformer {
  to(value: string[]): string {
    return JSON.stringify(value ?? []);
  }
  from(value: string): string[] {
    try {
      return value ? (JSON.parse(value) as string[]) : [];
    } catch {
      return [];
    }
  }
}

export enum ArticleStatus {
  DRAFT = 'draft',
  PUBLISHED = 'published',
  ARCHIVED = 'archived',
}

export enum LiveBlogStatus {
  DRAFT = 'draft',
  LIVE = 'live',
  ENDED = 'ended',
  ARCHIVED = 'archived',
}

export enum ImagePosition {
  TOP = 'top',
  LEFT = 'left',
  RIGHT = 'right',
  NONE = 'none',
}

export enum ImageSize {
  SMALL = 'small',
  MEDIUM = 'medium',
  LARGE = 'large',
}

export enum VideoPosition {
  TOP = 'top',
  INLINE = 'inline',
  BOTTOM = 'bottom',
  NONE = 'none',
}

export enum UserRole {
  ADMIN = 'admin',
  CONTRIBUTOR = 'contributor',
  USER = 'user',
}

export enum ReactionType {
  LIKE = 'like',
  DISLIKE = 'dislike',
}

@Entity('authors')
export class Author {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @Column({ unique: true })
  slug: string;

  @Column({ nullable: true })
  bio: string;

  @Column({ nullable: true })
  avatar: string;

  @Column({ default: false })
  isActive: boolean;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}

@Entity('categories')
export class Category {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @Column({ unique: true })
  slug: string;

  @Column({ nullable: true })
  description: string;

  @Column({ nullable: true })
  parentId: string;

  @Column({ default: 0 })
  order: number;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @ManyToOne(() => Category, { onDelete: 'SET NULL' })
  @JoinColumn({ name: 'parentId' })
  parent: Category;
}

@Entity('users')
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ unique: true })
  email: string;

  @Column({ unique: true })
  username: string;

  @Column()
  passwordHash: string;

  @Column({
    type: 'text',
    default: 'user',
  })
  role: UserRole;

  @Column({ default: true })
  isActive: boolean;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}

@Entity('articles')
export class Article {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  title: string;

  @Column('text')
  content: string;

  @Column({ type: 'text', nullable: true })
  excerpt: string;

  @Column({ default: '' })
  slug: string;

  @Column({ default: '' })
  featuredImage: string;

  @Column({
    type: 'text',
    default: 'top',
  })
  imagePosition: ImagePosition;

  @Column({
    type: 'text',
    default: 'medium',
  })
  imageSize: ImageSize;

  @Column({ default: '' })
  videoUrl: string;

  @Column({
    type: 'text',
    default: 'inline',
  })
  videoPosition: VideoPosition;

  @Column({ default: '' })
  videoCaption: string;

  @Column({
    type: 'text',
    default: '[]',
    transformer: new ArrayTransformer(),
  })
  tags: string[];

  @Column({
    type: 'text',
    default: 'draft',
  })
  status: ArticleStatus;

  @Column({ default: 0 })
  views: number;

  @Column({ nullable: true, unique: true })
  strapiId: string;

  @Column({ nullable: true })
  authorId: string;

  @Column({ nullable: true })
  categoryId: string;

  @Column({ type: 'text', nullable: true })
  ogTitle: string;

  @Column({ type: 'text', nullable: true })
  ogDescription: string;

  @Column({ type: 'text', nullable: true })
  ogImage: string;

  @Column({ type: 'text', nullable: true })
  twitterTitle: string;

  @Column({ type: 'text', nullable: true })
  twitterDescription: string;

  @Column({ type: 'text', nullable: true })
  twitterImage: string;

  @Column({ default: 0 })
  facebookShares: number;

  @Column({ default: 0 })
  twitterShares: number;

  @Column({ default: 0 })
  instagramShares: number;

  @Column({ default: 0 })
  tiktokShares: number;

  @Column({ default: 0 })
  telegramShares: number;

  @Column({ default: false })
  isHero: boolean;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @ManyToOne(() => Author, { onDelete: 'SET NULL' })
  @JoinColumn({ name: 'authorId' })
  author: Author;

  @ManyToOne(() => Category, { onDelete: 'SET NULL' })
  @JoinColumn({ name: 'categoryId' })
  category: Category;

  @OneToMany(() => Comment, (comment) => comment.article)
  comments: Comment[];

  @OneToMany(() => Reaction, (reaction) => reaction.article)
  reactions: Reaction[];
}

@Entity('live_blogs')
export class LiveBlog {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  title: string;

  @Column({ unique: true })
  slug: string;

  @Column({ type: 'text', nullable: true })
  description: string;

  @Column({
    type: 'text',
    default: 'draft',
  })
  status: LiveBlogStatus;

  @Column({ default: false })
  isPinned: boolean;

  @Column({ nullable: true, unique: true })
  strapiId: string;

  @Column({ nullable: true })
  authorId: string;

  @Column({ nullable: true })
  categoryId: string;

  @Column({ default: '' })
  featuredImage: string;

  @Column({
    type: 'text',
    default: 'top',
  })
  imagePosition: ImagePosition;

  @Column({
    type: 'text',
    default: 'medium',
  })
  imageSize: ImageSize;

  @Column({ default: '' })
  videoUrl: string;

  @Column({
    type: 'text',
    default: 'inline',
  })
  videoPosition: VideoPosition;

  @Column({ default: '' })
  videoCaption: string;

  @Column({ default: 0 })
  viewCount: number;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @ManyToOne(() => Author, { onDelete: 'SET NULL' })
  @JoinColumn({ name: 'authorId' })
  author: Author;

  @ManyToOne(() => Category, { onDelete: 'SET NULL' })
  @JoinColumn({ name: 'categoryId' })
  category: Category;

  @OneToMany(() => LiveBlogUpdate, (update) => update.liveBlog, {
    cascade: true,
  })
  updates: LiveBlogUpdate[];

  @OneToMany(() => Comment, (comment) => comment.liveBlog)
  comments: Comment[];

  @OneToMany(() => Reaction, (reaction) => reaction.liveBlog)
  reactions: Reaction[];
}

@Entity('live_blog_updates')
export class LiveBlogUpdate {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column('text')
  content: string;

  @Column({ default: false })
  isPinned: boolean;

  @Column({ nullable: true })
  authorId: string;

  @Column({ type: 'timestamp', nullable: true })
  scheduledAt: Date;

  @Column({ nullable: true })
  strapiId: string;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @ManyToOne(() => Author, { onDelete: 'SET NULL' })
  @JoinColumn({ name: 'authorId' })
  author: Author;

  @ManyToOne(() => LiveBlog, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'liveBlogId' })
  liveBlog: LiveBlog;
}

@Entity('comments')
export class Comment {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column('text')
  content: string;

  @Column({ nullable: true })
  articleId: string;

  @Column({ nullable: true })
  liveBlogId: string;

  @Column({ nullable: true })
  parentId: string;

  @Column()
  userId: string;

  @Column({ default: 0 })
  likeCount: number;

  @Column({ default: 0 })
  dislikeCount: number;

  @Column({ default: true })
  isVisible: boolean;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @ManyToOne(() => Article, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'articleId' })
  article: Article;

  @ManyToOne(() => LiveBlog, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'liveBlogId' })
  liveBlog: LiveBlog;

  @ManyToOne(() => Comment, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'parentId' })
  parent: Comment;

  @ManyToOne(() => User, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'userId' })
  user: User;

  @OneToMany(() => Comment, (comment) => comment.parent)
  replies: Comment[];
}

@Entity('reactions')
export class Reaction {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({
    type: 'text',
  })
  type: ReactionType;

  @Column({ nullable: true })
  articleId: string;

  @Column({ nullable: true })
  liveBlogId: string;

  @Column({ nullable: true })
  commentId: string;

  @Column()
  userId: string;

  @CreateDateColumn()
  createdAt: Date;

  @ManyToOne(() => Article, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'articleId' })
  article: Article;

  @ManyToOne(() => LiveBlog, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'liveBlogId' })
  liveBlog: LiveBlog;

  @ManyToOne(() => Comment, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'commentId' })
  comment: Comment;

  @ManyToOne(() => User, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'userId' })
  user: User;
}
