import { Injectable, NotFoundException, Inject, Optional, BadRequestException } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { PrismaService } from '../../common/prisma.service';
import { AuditService } from '../../common/audit.service';
import { CreateStationDto } from './stations.dto';

interface StationFilters {
  search?: string;
  country?: string;
  operational?: string;
}

@Injectable()
export class StationsService {
  constructor(
    private prisma: PrismaService,
    private auditService: AuditService,
    @Optional() @Inject(REQUEST) private request?: any,
  ) {}
  
  findAll(filters: StationFilters = {}) {
    const where: any = {};
    
    if (filters.search) {
      where.OR = [
        { name: { contains: filters.search, mode: 'insensitive' } },
        { code: { contains: filters.search, mode: 'insensitive' } },
        { city: { contains: filters.search, mode: 'insensitive' } },
      ];
    }
    
    if (filters.country) {
      where.countryCode = filters.country;
    }
    
    if (filters.operational !== undefined && filters.operational !== '') {
      where.isOperational = filters.operational === 'true';
    }
    
    return this.prisma.station.findMany({ 
      where,
      orderBy: { sequence: 'asc' } 
    }); 
  }
  
  async findOne(id: string) {
    const s = await this.prisma.station.findUnique({ where: { id } });
    if (!s) throw new NotFoundException('Station not found');
    return s;
  }
  
  async create(dto: CreateStationDto) {
    const station = await this.prisma.station.create({ data: dto });
    
    await this.auditService.log({
      userId: this.request?.user?.id,
      action: 'CREATE',
      entityType: 'Station',
      entityId: station.id,
      newData: station,
    });

    return station;
  }

  async update(id: string, dto: Partial<CreateStationDto>) {
    const oldStation = await this.findOne(id);
    const { code, name, city, timezone, lat, lng } = dto;
    const data: any = { code, name, city, timezone, lat, lng };
    if ('countryCode' in dto) data.countryCode = (dto as any).countryCode;
    if ('sequence' in dto) data.sequence = (dto as any).sequence;
    if ('isOperational' in dto) data.isOperational = (dto as any).isOperational;
    
    const updatedStation = await this.prisma.station.update({
      where: { id },
      data,
    });

    await this.auditService.log({
      userId: this.request?.user?.id,
      action: 'UPDATE',
      entityType: 'Station',
      entityId: id,
      oldData: oldStation,
      newData: updatedStation,
    });

    return updatedStation;
  }

  async remove(id: string) {
    const station = await this.findOne(id);
    const deleted = await this.prisma.station.delete({ where: { id } });

    await this.auditService.log({
      userId: this.request?.user?.id,
      action: 'DELETE',
      entityType: 'Station',
      entityId: id,
      oldData: station,
    });

    return deleted;
  }
}
