import { Injectable, NotFoundException } from '@nestjs/common'
import { InjectModel } from '@nestjs/mongoose'
import { Model, Types } from 'mongoose'
import { Hearing, HearingDocument } from '../common/schemas'
import { CreateHearingDto } from './dto/create-hearing.dto'
import { UpdateHearingDto } from './dto/update-hearing.dto'

@Injectable()
export class HearingsService {
  constructor(
    @InjectModel(Hearing.name) private hearingModel: Model<HearingDocument>,
  ) {}

  async create(dto: CreateHearingDto): Promise<HearingDocument> {
    const hearing = new this.hearingModel({ ...dto, status: 'scheduled' })
    return hearing.save()
  }

  async findAll(filters: {
    matterId?: string
    clientFolderId?: string
    status?: string
    from?: string
    to?: string
    limit?: number
    offset?: number
  }): Promise<{ items: HearingDocument[]; total: number }> {
    const query: any = {}
    if (filters.matterId) query.matterId = new Types.ObjectId(filters.matterId)
    if (filters.clientFolderId) query.clientFolderId = new Types.ObjectId(filters.clientFolderId)
    if (filters.status) query.status = filters.status
    if (filters.from || filters.to) {
      query.date = {}
      if (filters.from) query.date.$gte = new Date(filters.from)
      if (filters.to) query.date.$lte = new Date(filters.to)
    }

    const [items, total] = await Promise.all([
      this.hearingModel.find(query)
        .sort({ date: 1 })
        .skip(filters.offset ?? 0)
        .limit(filters.limit ?? 50)
        .exec(),
      this.hearingModel.countDocuments(query),
    ])
    return { items, total }
  }

  async findUpcoming(days = 7): Promise<HearingDocument[]> {
    const from = new Date()
    const to = new Date()
    to.setDate(to.getDate() + days)
    return this.hearingModel.find({
      date: { $gte: from, $lte: to },
      status: 'scheduled',
    }).sort({ date: 1 }).exec()
  }

  async findOne(id: string): Promise<HearingDocument> {
    const hearing = await this.hearingModel.findById(id).exec()
    if (!hearing) throw new NotFoundException(`Hearing ${id} not found`)
    return hearing
  }

  async update(id: string, dto: UpdateHearingDto): Promise<HearingDocument> {
    const hearing = await this.hearingModel.findByIdAndUpdate(id, dto, { new: true }).exec()
    if (!hearing) throw new NotFoundException(`Hearing ${id} not found`)
    return hearing as HearingDocument
  }

  async recordOutcome(id: string, outcome: string): Promise<HearingDocument> {
    const hearing = await this.hearingModel.findByIdAndUpdate(
      id,
      { status: 'completed', outcome },
      { new: true },
    ).exec()
    if (!hearing) throw new NotFoundException(`Hearing ${id} not found`)
    return hearing as HearingDocument
  }
}
