import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from '../../../database/entities/user.entity';

@Injectable()
export class FamiliesService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
  ) {}

  async listFamilies() {
    // Get all families with their members and children
    const familiesRaw = await this.userRepository.query(`
      SELECT
        f.id,
        f.name,
        f.created_at as "createdAt",
        COUNT(DISTINCT fm.user_id) as "memberCount",
        COUNT(DISTINCT c.id) as "childrenCount",
        COALESCE(act.activity_count, 0) as "activityCount",
        COALESCE(act.last_activity_at, f.created_at) as "lastActivityAt"
      FROM families f
      LEFT JOIN family_members fm ON f.id = fm.family_id
      LEFT JOIN children c ON f.id = c.family_id
      LEFT JOIN LATERAL (
        SELECT
          COUNT(*) as activity_count,
          MAX(created_at) as last_activity_at
        FROM activities a
        WHERE a.child_id IN (SELECT id FROM children WHERE family_id = f.id)
      ) act ON true
      GROUP BY f.id, f.name, f.created_at, act.activity_count, act.last_activity_at
      ORDER BY f.created_at DESC
    `);

    // Get members for each family
    const families = await Promise.all(
      familiesRaw.map(async (family: any) => {
        const members = await this.userRepository.query(
          `
          SELECT
            u.id,
            u.name,
            u.email,
            fm.role,
            fm.joined_at as "joinedAt"
          FROM family_members fm
          JOIN users u ON fm.user_id = u.id
          WHERE fm.family_id = $1
          ORDER BY fm.joined_at ASC
        `,
          [family.id],
        );

        const children = await this.userRepository.query(
          `
          SELECT
            id,
            name,
            birth_date as "birthDate",
            gender,
            display_color as "displayColor"
          FROM children
          WHERE family_id = $1
          ORDER BY birth_date DESC
        `,
          [family.id],
        );

        return {
          ...family,
          memberCount: parseInt(family.memberCount, 10),
          childrenCount: parseInt(family.childrenCount, 10),
          activityCount: parseInt(family.activityCount, 10),
          members,
          children,
        };
      }),
    );

    return { data: families };
  }

  async getFamilyById(id: string) {
    const familyRaw = await this.userRepository.query(
      `
      SELECT
        f.id,
        f.name,
        f.created_at as "createdAt",
        COUNT(DISTINCT fm.user_id) as "memberCount",
        COUNT(DISTINCT c.id) as "childrenCount"
      FROM families f
      LEFT JOIN family_members fm ON f.id = fm.family_id
      LEFT JOIN children c ON f.id = c.family_id
      WHERE f.id = $1
      GROUP BY f.id, f.name, f.created_at
    `,
      [id],
    );

    if (!familyRaw || familyRaw.length === 0) {
      throw new NotFoundException(`Family with ID ${id} not found`);
    }

    const family = familyRaw[0];

    const members = await this.userRepository.query(
      `
      SELECT
        u.id,
        u.name,
        u.email,
        fm.role,
        fm.joined_at as "joinedAt"
      FROM family_members fm
      JOIN users u ON fm.user_id = u.id
      WHERE fm.family_id = $1
      ORDER BY fm.joined_at ASC
    `,
      [id],
    );

    const children = await this.userRepository.query(
      `
      SELECT
        id,
        name,
        birth_date as "birthDate",
        gender,
        display_color as "displayColor"
      FROM children
      WHERE family_id = $1
      ORDER BY birth_date DESC
    `,
      [id],
    );

    const activityStats = await this.userRepository.query(
      `
      SELECT
        COUNT(*) as activity_count,
        MAX(created_at) as last_activity_at
      FROM activities
      WHERE child_id IN (SELECT id FROM children WHERE family_id = $1)
    `,
      [id],
    );

    return {
      ...family,
      memberCount: parseInt(family.memberCount, 10),
      childrenCount: parseInt(family.childrenCount, 10),
      activityCount: parseInt(activityStats[0]?.activity_count || '0', 10),
      lastActivityAt: activityStats[0]?.last_activity_at || family.createdAt,
      members,
      children,
    };
  }

  async deleteFamily(id: string) {
    // Check if family exists
    const family = await this.userRepository.query(
      'SELECT id FROM families WHERE id = $1',
      [id],
    );

    if (!family || family.length === 0) {
      throw new NotFoundException(`Family with ID ${id} not found`);
    }

    // Delete family (cascading will handle members and children)
    await this.userRepository.query('DELETE FROM families WHERE id = $1', [
      id,
    ]);

    return { message: 'Family deleted successfully' };
  }
}
