import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSource, MoreThan, Repository } from 'typeorm';
import { Section } from '../sections/section.entity';
import { Module as ModuleEntity } from '../modules/module.entity';
import { Lesson } from '../lessons/lesson.entity';
import { Activity } from '../activities/activity.entity';
import { Media } from '../media/media.entity';
import { Case } from '../cases/case.entity';
import { Drawing } from '../drawings/drawing.entity';
import { Progress } from '../progress/progress.entity';
import { AnonymousSession } from '../anonymous-sessions/anonymous-session.entity';

export interface DashboardSummary {
  sections: { total: number; published: number };
  modules: { total: number; published: number; draft: number; inReview: number };
  lessons: { total: number };
  activities: { total: number; published: number };
  media: { total: number };
  cases: { total: number };
  drawings: { total: number };
  sessions: { total: number; activeLast30Days: number };
  completions: { total: number };
}

@Injectable()
export class AnalyticsService {
  constructor(
    @InjectRepository(Section) private readonly sections: Repository<Section>,
    @InjectRepository(ModuleEntity) private readonly modules: Repository<ModuleEntity>,
    @InjectRepository(Lesson) private readonly lessons: Repository<Lesson>,
    @InjectRepository(Activity) private readonly activities: Repository<Activity>,
    @InjectRepository(Media) private readonly media: Repository<Media>,
    @InjectRepository(Case) private readonly cases: Repository<Case>,
    @InjectRepository(Drawing) private readonly drawings: Repository<Drawing>,
    @InjectRepository(Progress) private readonly progress: Repository<Progress>,
    @InjectRepository(AnonymousSession)
    private readonly sessions: Repository<AnonymousSession>,
    private readonly dataSource: DataSource,
  ) {}

  async summary(): Promise<DashboardSummary> {
    const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);

    const [
      sectionsTotal,
      sectionsPublished,
      modulesTotal,
      modulesPublished,
      modulesDraft,
      modulesInReview,
      lessonsTotal,
      activitiesTotal,
      activitiesPublished,
      mediaTotal,
      casesTotal,
      drawingsTotal,
      sessionsTotal,
      sessionsActive,
      completionsTotal,
    ] = await Promise.all([
      this.sections.count(),
      this.sections.count({ where: { status: 'PUBLISHED' } }),
      this.modules.count(),
      this.modules.count({ where: { status: 'PUBLISHED' } }),
      this.modules.count({ where: { status: 'DRAFT' } }),
      this.modules.count({ where: { status: 'IN_REVIEW' } }),
      this.lessons.count(),
      this.activities.count(),
      this.activities.count({ where: { status: 'PUBLISHED' } }),
      this.media.count({ where: { status: 'ACTIVE' } }),
      this.cases.count(),
      this.drawings.count(),
      this.sessions.count(),
      this.sessions.count({ where: { lastSeen: MoreThan(thirtyDaysAgo) } }),
      this.progress.count(),
    ]);

    return {
      sections: { total: sectionsTotal, published: sectionsPublished },
      modules: {
        total: modulesTotal,
        published: modulesPublished,
        draft: modulesDraft,
        inReview: modulesInReview,
      },
      lessons: { total: lessonsTotal },
      activities: { total: activitiesTotal, published: activitiesPublished },
      media: { total: mediaTotal },
      cases: { total: casesTotal },
      drawings: { total: drawingsTotal },
      sessions: { total: sessionsTotal, activeLast30Days: sessionsActive },
      completions: { total: completionsTotal },
    };
  }

  /** Modules ranked by how many sessions have progress recorded against them. */
  async topModules(limit = 10) {
    return this.dataSource.query(
      `SELECT m.id, m.title, m.status,
              COUNT(DISTINCT p.anonymous_session_id) AS learners,
              COUNT(p.id) AS interactions
       FROM progress p
       JOIN modules m ON m.id = p.entity_id
       WHERE p.entity_type = 'module'
       GROUP BY m.id, m.title, m.status
       ORDER BY learners DESC, interactions DESC
       LIMIT ?`,
      [limit],
    );
  }

  /** Which activity types learners actually engage with. */
  async activityUsage() {
    return this.dataSource.query(
      `SELECT a.type,
              COUNT(DISTINCT a.id) AS activities,
              COUNT(p.id) AS interactions
       FROM activities a
       LEFT JOIN progress p ON p.entity_type = 'activity' AND p.entity_id = a.id
       GROUP BY a.type
       ORDER BY interactions DESC`,
    );
  }

  /** Daily counts for the dashboard trend chart. */
  async engagementTrend(days = 30) {
    return this.dataSource.query(
      `SELECT DATE(last_updated) AS day, COUNT(*) AS interactions
       FROM progress
       WHERE last_updated >= DATE_SUB(CURDATE(), INTERVAL ? DAY)
       GROUP BY DATE(last_updated)
       ORDER BY day ASC`,
      [days],
    );
  }

  async drawingUsage(limit = 10) {
    return this.dataSource.query(
      `SELECT a.id, a.title, a.type, COUNT(d.id) AS drawings
       FROM drawings d
       JOIN activities a ON a.id = d.activity_id
       GROUP BY a.id, a.title, a.type
       ORDER BY drawings DESC
       LIMIT ?`,
      [limit],
    );
  }

  /** Completion ratio per section, derived from activity-level progress. */
  async sectionCompletion() {
    return this.dataSource.query(
      `SELECT s.id, s.title,
              COUNT(DISTINCT a.id) AS total_activities,
              COUNT(DISTINCT p.entity_id) AS engaged_activities
       FROM sections s
       LEFT JOIN modules m ON m.section_id = s.id
       LEFT JOIN lessons l ON l.module_id = m.id
       LEFT JOIN activities a ON a.lesson_id = l.id
       LEFT JOIN progress p ON p.entity_type = 'activity' AND p.entity_id = a.id
       GROUP BY s.id, s.title
       ORDER BY s.order_index ASC`,
    );
  }
}
