"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var ShopService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ShopService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("typeorm");
const typeorm_2 = require("@nestjs/typeorm");
const shop_entity_1 = require("../../common/shop/shop.entity");
const review_entity_1 = require("../../common/review/review.entity");
const offer_entity_1 = require("../../common/offer/offer.entity");
const moment = require("moment");
const geolib_1 = require("geolib");
let ShopService = ShopService_1 = class ShopService {
    constructor(shopRepository, reviewRepository, offerRepository) {
        this.shopRepository = shopRepository;
        this.reviewRepository = reviewRepository;
        this.offerRepository = offerRepository;
        this.logger = new common_1.Logger(ShopService_1.name);
    }
    async getAllCities() {
        const rows = await this.shopRepository
            .createQueryBuilder('s')
            .select('DISTINCT s.city', 'city')
            .where('s.city IS NOT NULL')
            .andWhere("s.city != ''")
            .getRawMany();
        return rows.map((r) => r.city);
    }
    async findActive(lang, filters = {}, list_type, offerid, userLat, userLon, radiusKm = 5, latestType, city) {
        if (city) {
            filters.city = city;
        }
        let shops = await this.shopRepository.find({
            where: filters,
            order: { createdAt: 'DESC' },
            relations: ["services", "schedules", "highlights", "contact", "category"],
        });
        const today = moment().format('YYYY-MM-DD');
        if (userLat && userLon) {
            shops = shops.filter(shop => {
                const shopLat = Number(shop.latitude);
                const shopLon = Number(shop.longitude);
                if (!shopLat || !shopLon)
                    return false;
                const currentLocation = {
                    latitude: Number(userLat),
                    longitude: Number(userLon),
                };
                const destination = {
                    latitude: Number(shopLat),
                    longitude: Number(shopLon),
                };
                const distanceMeters = (0, geolib_1.getDistance)(currentLocation, destination);
                return distanceMeters <= radiusKm * 1000;
            });
        }
        const shopSummaryPromises = shops.map(async (shop) => {
            const queryBuilder = this.offerRepository.createQueryBuilder('offer')
                .innerJoin('shop_offers', 'shopOffer', 'shopOffer.offerId = offer.id')
                .select([
                'offer.id AS offer_id',
                'offer.name AS offer_name',
                'offer.startDate AS start_date',
                'offer.endDate AS end_date',
                'offer.discount AS discount',
                'shopOffer.offer_discount AS offer_discount',
                'shopOffer.shopId AS shop_id',
                'shopOffer.status AS shop_offer_status'
            ])
                .where('shopOffer.shopId = :shopId', { shopId: shop.id })
                .andWhere('offer.startDate <= :today', { today })
                .andWhere('offer.endDate >= :today', { today });
            if (offerid) {
                queryBuilder.andWhere('offer.id = :offerid', { offerid });
            }
            const offerSummary = await queryBuilder.getRawOne();
            const reviewSummary = await this.reviewRepository
                .createQueryBuilder('review')
                .select('AVG(review.rating)', 'averageRating')
                .addSelect('COUNT(review.id)', 'totalReviews')
                .where('review.shopId = :shopId', { shopId: shop.id })
                .getRawOne();
            const shopData = {
                shop: {
                    id: shop.id,
                    name: shop[`name_${lang}`] || shop.name,
                    address: shop[`address_${lang}`] || shop.address,
                    description: shop[`description_${lang}`] || shop.description,
                    slug: shop.slug,
                    userId: shop.userId,
                    is_featured: shop.is_featured,
                    quick_response: shop.quick_response,
                    business_year: shop.business_year,
                    shop_featured: shop.shop_featured,
                    logo: shop.logo,
                    image: shop.image,
                    video: shop.video,
                    videothamnail: shop.videothamnail,
                    galleries: shop.galleries,
                    status: shop.status,
                    createdAt: shop.createdAt,
                    updatedAt: shop.updatedAt,
                    latitude: shop.latitude,
                    longitude: shop.longitude,
                    map_address: shop.map_address,
                    city: shop.city,
                    services: shop.services,
                    schedules: shop.schedules,
                    highlights: shop.highlights,
                    category: {
                        id: shop.category?.id,
                        image: shop.category?.image,
                        video: shop.category?.video,
                        videothamnail: shop.category?.videothamnail,
                        status: shop.category?.status,
                        createdAt: shop.category?.createdAt,
                        updatedAt: shop.category?.updatedAt,
                        name: shop.category?.[`name_${lang}`] || shop.category?.name,
                        description: shop.category?.[`description_${lang}`] || shop.category?.description,
                    },
                    contact: {
                        id: shop.contact?.id,
                        website: shop.contact?.website,
                        email: shop.contact?.email,
                        phoneNumber: shop.contact?.phoneNumber,
                        whatsappNumber: shop.contact?.whatsappNumber,
                        contactpersionimg: shop.contact?.contactpersionimg,
                        facebook: shop.contact?.facebook,
                        twitter: shop.contact?.twitter,
                        linkedin: shop.contact?.linkedin,
                        instagram: shop.contact?.instagram,
                        snapchat: shop.contact?.snapchat,
                        youtube: shop.contact?.youtube,
                        tiktok: shop.contact?.tiktok,
                        contactpersionname: shop.contact?.[`contactpersionname_${lang}`] || shop.contact?.contactpersionname,
                        designation: shop.contact?.[`designation_${lang}`] || shop.contact?.designation,
                    },
                },
                reviewSummary: {
                    averageRating: reviewSummary?.averageRating || 0,
                    totalReviews: reviewSummary?.totalReviews || 0,
                },
                offer: (offerSummary && offerSummary.shop_offer_status === 'active') ? (offerSummary.offer_discount || 0) : null,
            };
            if (list_type === 'offer' && (!offerSummary || offerSummary.shop_offer_status !== 'active')) {
                return null;
            }
            return shopData;
        });
        let shopResults = await Promise.all(shopSummaryPromises);
        shopResults = shopResults.filter(shop => shop !== null);
        if (latestType === 'latest') {
            shopResults.sort((a, b) => new Date(b.shop.createdAt).getTime() - new Date(a.shop.createdAt).getTime());
        }
        if (city) {
            shopResults = shopResults.filter(item => item.shop.city && item.shop.city.toLowerCase() === city.toLowerCase());
        }
        return shopResults;
    }
    async findOne(id, lang) {
        const shop = await this.shopRepository.findOne({
            where: { id },
            relations: ["services", "schedules", "highlights", "contact"],
        });
        if (!shop)
            return null;
        const nameField = `name_${lang}`;
        const descriptionField = `description_${lang}`;
        const addressField = `address_${lang}`;
        shop.name = shop[nameField] || shop.name;
        shop.description = shop[descriptionField] || shop.description;
        shop.address = shop[addressField] || shop.address;
        shop.services = shop.services?.map(service => {
            const serviceNameField = `name_${lang}`;
            return {
                ...service,
                name: service[serviceNameField] || service.name,
            };
        });
        shop.highlights = shop.highlights?.map(highlight => {
            const titleField = `title_${lang}`;
            return {
                ...highlight,
                title: highlight[titleField] || highlight.title,
            };
        });
        if (shop.contact) {
            shop.contact.contactpersionname = shop.contact[`contactpersionname_${lang}`] || shop.contact.contactpersionname;
            shop.contact.designation = shop.contact[`designation_${lang}`] || shop.contact.designation;
        }
        const ratingSummary = await this.reviewRepository
            .createQueryBuilder('review')
            .select('AVG(review.rating)', 'averageRating')
            .addSelect('COUNT(review.id)', 'totalReviews')
            .where('review.shopId = :id', { id })
            .getRawOne();
        const averageRating = ratingSummary?.averageRating || 0;
        const totalReviews = ratingSummary?.totalReviews || 0;
        const reviews = await this.reviewRepository
            .createQueryBuilder('review')
            .leftJoinAndSelect('users', 'user', 'user.id = review.userId')
            .select([
            'review.id AS review_id',
            'review.userId AS review_userId',
            'review.shopId AS review_shopId',
            'review.comment AS review_comment',
            'review.rating AS review_rating',
            'review.galleries AS review_galleries',
            'review.status AS review_status',
            'user.name AS userName',
            'user.email AS userEmail',
            'user.mobileNumber AS userMobileNumber',
            'user.userPhoto AS userPhoto',
            'review.createdAt AS review_createdAt',
            'review.updatedAt AS review_updatedAt',
        ])
            .where('review.shopId = :id', { id })
            .getRawMany();
        return {
            shop,
            reviews,
            ratingSummary: {
                averageRating,
                totalReviews,
            },
        };
    }
    async findActiveSearch(lang, search) {
        const safeLang = ['en', 'urd', 'ar'].includes(lang) ? lang : 'en';
        const qb = this.shopRepository.createQueryBuilder('shop');
        qb.where('shop.status = :status', { status: 'active' });
        if (search && search.length >= 3) {
            if (safeLang === 'en') {
                qb.andWhere('shop.name LIKE :search', {
                    search: `%${search}%`,
                });
            }
            else {
                const nameColumn = `name_${safeLang}`;
                qb.andWhere(`shop.${nameColumn} LIKE :search`, {
                    search: `%${search}%`,
                });
            }
        }
        const shops = await qb.getMany();
        return this.applyLanguageToShops(shops, safeLang);
    }
    applyLanguageToShops(shops, lang) {
        if (lang === 'en') {
            return shops;
        }
        const nameField = `name_${lang}`;
        const descriptionField = `description_${lang}`;
        const addressField = `address_${lang}`;
        return shops.map((shop) => {
            const s = { ...shop };
            s.name = shop[nameField] || shop.name;
            s.description = shop[descriptionField] || shop.description;
            s.address = shop[addressField] || shop.address;
            return s;
        });
    }
};
exports.ShopService = ShopService;
exports.ShopService = ShopService = ShopService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_2.InjectRepository)(shop_entity_1.Shop)),
    __param(1, (0, typeorm_2.InjectRepository)(review_entity_1.Review)),
    __param(2, (0, typeorm_2.InjectRepository)(offer_entity_1.Offer)),
    __metadata("design:paramtypes", [typeorm_1.Repository,
        typeorm_1.Repository,
        typeorm_1.Repository])
], ShopService);
//# sourceMappingURL=shop.service.js.map