import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { JobApplications } from './entities/job_applications.entity';
import { brevoApiKey } from '../../config/common';
import { WhatsAppNotificationService } from '../notifications/whatsapp-notification.service';
import { EmailService } from '../email/email.service';
import { UserNotificationsService } from '../user_notifications/user_notifications.service';

@Injectable()
export class JobApplicationsService {
  constructor(
    @InjectRepository(JobApplications)
    private jobApplicationsRepository: Repository<JobApplications>,
    private notificationService: WhatsAppNotificationService, // Injected dependency
    private emailService: EmailService,
    private readonly userNotificationsService: UserNotificationsService,
  ) {}

  async findAll(): Promise<JobApplications[]> {
    return this.jobApplicationsRepository.find();
  }

  async updateStatus(id: number, status: string): Promise<JobApplications> {
    const validStatuses = [
      'Applied',
      'Shortlisted',
      'Interview',
      'Hired',
      'Rejected',
    ];
    if (!validStatuses.includes(status)) {
      throw new Error('Invalid status');
    }

    await this.jobApplicationsRepository.update(id, { status });
    const updated = await this.jobApplicationsRepository.findOne({
      where: { id },
    });

    // --- Notification Logic Start ---
    if (updated) {
      // Fetch details using raw query as before, but mapped for both Email and WhatsApp
      const [details] = await this.jobApplicationsRepository.query(
        `SELECT
           ja.id,
           ja.status,
           jp.title AS job_title,
           ja.job_post_id,
           sp.id AS seeker_id,
           sp.user_id AS recipient_user_id,
           u.email AS candidate_email,
           u.full_name AS candidate_name,
           u.username AS candidate_username,
           c.city_name AS city_name,
           s.state_name AS state_name,
           comp.name AS company_name
         FROM job_applications ja
         INNER JOIN job_posts jp ON ja.job_post_id = jp.id
         INNER JOIN seeker_profiles sp ON ja.seeker_id = sp.id
         INNER JOIN users u ON sp.user_id = u.id
         LEFT JOIN city c ON jp.city_id = c.city_id
         LEFT JOIN state s ON jp.state_id = s.state_id
         LEFT JOIN companies comp ON jp.company_id = comp.id
         WHERE ja.id = ?
         LIMIT 1`,
        [id],
      );

      if (details) {
        // 1. Existing Email Logic (Preserved)
        if (
          ['Shortlisted', 'Interview', 'Hired', 'Rejected'].includes(status) &&
          brevoApiKey &&
          details.candidate_email
        ) {
          this.sendEmail(status, details);
        }

        // 2. NEW WhatsApp Logic
        let templateName = '';
        const location =
          details.city_name && details.state_name
            ? `${details.city_name}, ${details.state_name}`
            : details.city_name || details.state_name || '';

        // Default payload for 'Applied' status (Legacy numeric keys)
        let payload: any = {
          1: details.candidate_name || 'Candidate', // {{1}} Name
          2: details.job_title || 'Job', // {{2}} Job Title
          3: location, // {{3}} Location
        };

        let inAppMessage = '';
        switch (status) {
          case 'Applied':
            templateName = 'candidate_application_submitted';
            inAppMessage = `Your application for "${details.job_title || 'Job'}" in "${location || 'India'}" has been successfully submitted.`;
            break;
          case 'Shortlisted':
            templateName = 'candidate_shortlisted';
            payload = {
              candidate_name: details.candidate_name || 'Candidate',
              job_title: details.job_title || 'Job',
              job_location: location,
            };
            inAppMessage = `Congratulations! You have been shortlisted for the role of "${details.job_title || 'Job'}" in "${location || 'India'}".`;
            break;
          case 'Interview':
            templateName = 'candidate_interview_contact_expected';
            payload = {
              candidate_name: details.candidate_name || 'Candidate',
              job_title: details.job_title || 'Job',
              job_location: location,
            };
            inAppMessage = `Interview Update: The employer has reviewed your profile for "${details.job_title || 'Job'}" in "${location || 'India'}". They may contact you soon.`;
            break;
          case 'Rejected':
            templateName = 'candidate_application_rejected';
            payload = {
              candidate_name: details.candidate_name || 'Candidate',
              job_title: details.job_title || 'Job',
            };
            inAppMessage = `Thank you for applying to "${details.job_title || 'Job'}". The employer has decided to move forward with other candidates at this time.`;
            break;
        }

        if (templateName) {
          // Fire and forget - don't await to avoid blocking response
          this.notificationService
            .createEvent(
              templateName,
              details.recipient_user_id,
              'job_application',
              id,
              payload,
            )
            .catch((err) =>
              console.error('Failed to create notification event', err),
            );
        }

        if (inAppMessage && details.recipient_user_id) {
          this.userNotificationsService
            .createNotification(
              details.recipient_user_id,
              'application_status',
              inAppMessage
            )
            .catch((err) =>
              console.error('Failed to create in-app notification for candidate (status update)', err),
            );
        }
      }
    }
    // --- Notification Logic End ---

    return updated as JobApplications;
  }

  // Refactored helper for the existing email code to keep updateStatus clean
  private async sendEmail(status: string, details: any) {
    if (!details.candidate_email) return;

    const preferredName =
      details.candidate_name ||
      details.candidate_username ||
      (details.candidate_email || '').split('@')[0];

    const templateName = 'application_status_update';
    
    const context = {
      preferred_name: preferredName,
      job_title: details.job_title || 'a position',
      company_name: details.company_name || 'the company',
      status: status
    };

    try {
      await this.emailService.sendTemplateEmail(
        templateName,
        details.candidate_email,
        preferredName,
        context
      );
    } catch (e) {
      console.error('Email send failed', e);
    }
  }

  async findByJobPost(jobPostId: number): Promise<JobApplications[]> {
    return this.jobApplicationsRepository.find({
      where: { job_post_id: jobPostId },
      order: { applied_at: 'DESC' },
    });
  }

  async findBySeeker(seekerId: number): Promise<JobApplications[]> {
    return this.jobApplicationsRepository.find({
      where: { seeker_id: seekerId },
      order: { applied_at: 'DESC' },
    });
  }
}
