import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../../prisma/prisma.service';

export interface SessionData {
  customerName?: string;
  deliveryMethod?: string;
  deliveryAddress?: string;
  deliveryLat?: number;
  deliveryLng?: number;
  selectedCategoryId?: string;
  selectedProductId?: string;
  lastProductList?: string[]; // IDs of products printed in last list for index matching
  lastCategoryList?: string[]; // IDs of categories printed in last list
  // EcoCash seamless payment fields
  pendingOrderId?: string;       // order ID waiting for EcoCash payment
  pendingPaymentRef?: string;    // reference returned by PesePay after initiation
  ecocashNumber?: string;        // collected EcoCash phone number
  amount?: number;               // pending payment amount
  currency?: string;             // pending payment currency
}

@Injectable()
export class WhatsAppSessionService {
  constructor(private readonly prisma: PrismaService) {}

  async getOrCreateSession(businessId: string, whatsappNumber: string, customerId: string) {
    let session = await this.prisma.session.findFirst({
      where: {
        whatsappNumber,
      },
    });

    const expiryTime = new Date(Date.now() + 60 * 60 * 1000); // 1 hour expiry

    // Determine default initial step based on business count
    const activeBusinessesCount = await this.prisma.business.count({
      where: { status: 'ACTIVE' },
    });
    const defaultStep = activeBusinessesCount > 1 ? 'SELECT_STORE' : 'WELCOME';

    if (!session) {
      session = await this.prisma.session.create({
        data: {
          businessId,
          customerId,
          whatsappNumber,
          currentStep: defaultStep,
          sessionDataJson: '{}',
          expiresAt: expiryTime,
        },
      });
    } else if (session.expiresAt < new Date()) {
      // Session expired, reset
      session = await this.prisma.session.update({
        where: { id: session.id },
        data: {
          currentStep: defaultStep,
          sessionDataJson: '{}',
          expiresAt: expiryTime,
        },
      });
    } else {
      // Session is active, extend its expiration time (sliding expiration)
      session = await this.prisma.session.update({
        where: { id: session.id },
        data: {
          expiresAt: expiryTime,
        },
      });
    }

    return session;
  }

  async updateStep(sessionId: string, step: string) {
    return this.prisma.session.update({
      where: { id: sessionId },
      data: {
        currentStep: step,
        expiresAt: new Date(Date.now() + 60 * 60 * 1000), // bump expiry
      },
    });
  }

  async updateSessionData(sessionId: string, data: Partial<SessionData>) {
    const session = await this.prisma.session.findUnique({
      where: { id: sessionId },
    });

    if (!session) return null;

    let currentData: SessionData = {};
    try {
      currentData = JSON.parse(session.sessionDataJson);
    } catch {
      currentData = {};
    }

    const mergedData = { ...currentData, ...data };

    return this.prisma.session.update({
      where: { id: sessionId },
      data: {
        sessionDataJson: JSON.stringify(mergedData),
        expiresAt: new Date(Date.now() + 60 * 60 * 1000), // bump expiry
      },
    });
  }

  async clearSession(sessionId: string) {
    const activeBusinessesCount = await this.prisma.business.count({
      where: { status: 'ACTIVE' },
    });
    const defaultStep = activeBusinessesCount > 1 ? 'SELECT_STORE' : 'WELCOME';

    return this.prisma.session.update({
      where: { id: sessionId },
      data: {
        currentStep: defaultStep,
        sessionDataJson: '{}',
        expiresAt: new Date(Date.now() + 60 * 60 * 1000), // reset expiry
      },
    });
  }
}
