import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Area } from './entities/area.entity';

@Injectable()
export class AreaService {
  constructor(
    @InjectRepository(Area)
    private areaRepository: Repository<Area>,
  ) {}

  async getAllPincodes(): Promise<{ pincode: string }[]> {
    // Get unique pincodes
    const pincodes = await this.areaRepository
      .createQueryBuilder('area')
      .select('DISTINCT area.pincode', 'pincode')
      .where('area.pincode IS NOT NULL')
      .andWhere('area.status = :status', { status: 1 })
      .orderBy('area.pincode', 'ASC')
      .getRawMany();

    return pincodes;
  }

  async getAreasByPincode(pincode: string, status?: number): Promise<any[]> {
    const query = this.areaRepository
      .createQueryBuilder('area')
      .leftJoin('city', 'city', 'city.city_id = area.city_id')
      .leftJoin('state', 'state', 'state.state_id = city.state_id')
      .leftJoin('country', 'country', 'country.country_id = state.country_id')
      .select([
        'area.id AS id',
        'area.area AS area',
        'area.pincode AS pincode',
        'area.city_id AS city_id',
        'area.latitude AS latitude',
        'area.longitude AS longitude',
        'area.status AS status',
        'area.created_at AS created_at',
        'area.updated_at AS updated_at',
        'city.city_name AS city_name',
        'state.state_id AS state_id',
        'state.state_name AS state_name',
        'country.country_id AS country_id',
        'country.country_name AS country_name',
      ])
      .where('area.pincode = :pincode', { pincode });

    if (status !== undefined) {
      query.andWhere('area.status = :status', { status });
    }

    query.orderBy('area.area', 'ASC');

    return query.getRawMany();
  }

  async getAreas(status?: number): Promise<Area[]> {
    const where: any = {};
    if (status !== undefined) where.status = status;
    return this.areaRepository.find({
      where,
      order: { area: 'ASC' },
    });
  }
  async findByCity(
    cityId: number,
    page: number = 1,
    limit: number = 10,
    status?: number,
  ) {
    const skip = (page - 1) * limit;
    const where: any = { city_id: cityId };
    if (status !== undefined) where.status = status;

    const [data, total] = await this.areaRepository.findAndCount({
      where,
      skip,
      take: limit,
      order: { area: 'ASC' },
    });

    return {
      success: true,
      data,
      meta: {
        totalItems: total,
        itemsPerPage: limit,
        currentPage: page,
        totalPages: Math.ceil(total / limit),
      },
    };
  }

  async findOne(id: number): Promise<Area> {
    return this.areaRepository.findOne({ where: { id } });
  }

  async create(createAreaDto: any): Promise<any> {
    const newArea = this.areaRepository.create(createAreaDto);
    return this.areaRepository.save(newArea);
  }

  async update(id: number, updateAreaDto: any): Promise<any> {
    await this.areaRepository.update(id, updateAreaDto);
    return this.areaRepository.findOne({ where: { id } });
  }

  async remove(id: number): Promise<void> {
    await this.areaRepository.delete(id);
  }
}
