import db from '../../config/database';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '../../utils/logger';

export enum PaymentStatus {
  PENDING = 'PENDING',
  COMPLETED = 'COMPLETED',
  FAILED = 'FAILED',
  REFUNDED = 'REFUNDED',
  PROCESSING = 'PROCESSING'
}

export enum PaymentMethod {
  CREDIT_CARD = 'CREDIT_CARD',
  PAYPAL = 'PAYPAL',
  BANK_TRANSFER = 'BANK_TRANSFER',
  ALIPAY = 'ALIPAY',
  WECHAT_PAY = 'WECHAT_PAY'
}

export enum PaymentType {
  FEATURE = 'FEATURE',
  ORDER = 'ORDER',
  SUBSCRIPTION = 'SUBSCRIPTION',
  REFUND = 'REFUND'
}

export interface PaymentData {
  tenantId: string;
  shopId: string;
  amount: number;
  currency: string;
  method: PaymentMethod;
  type: PaymentType;
  relatedId: string;
  traceId: string;
  taskId: string;
  businessType: 'TOC' | 'TOB';
}

export interface Payment {
  id: string;
  tenantId: string;
  shopId: string;
  orderId?: string;
  amount: number;
  currency: string;
  status: 'PENDING' | 'COMPLETED' | 'FAILED' | 'REFUNDED';
  paymentMethod: string;
  transactionId: string;
  method?: string;
  type?: string;
  relatedId?: string;
  traceId?: string;
  taskId?: string;
  businessType?: string;
  createdAt: Date;
  updatedAt: Date;
}

export class PaymentService {
  private static readonly TABLE = 'cf_payment';

  static async createPayment(paymentData: Partial<Payment>): Promise<Payment> {
    const id = uuidv4();
    const transactionId = paymentData.transactionId || `TXN_${uuidv4()}`;
    
    await db(this.TABLE).insert({
      id,
      ...paymentData,
      paymentMethod: paymentData.paymentMethod || paymentData.method,
      transactionId,
      status: paymentData.status || 'PENDING',
      createdAt: new Date(),
      updatedAt: new Date()
    });
    
    return (await this.getPaymentById(id))!;
  }

  static async getPaymentById(id: string): Promise<Payment | null> {
    return await db(this.TABLE).where({ id }).first();
  }

  static async getPayment(orderId: string, traceId: string): Promise<Payment | null> {
    return await db(this.TABLE)
      .where({ orderId })
      .orderBy('createdAt', 'desc')
      .first();
  }

  static async updatePaymentStatus(orderId: string, status: Payment['status'], traceId: string): Promise<Payment | null> {
    const payment = await this.getPayment(orderId, traceId);
    if (!payment) return null;
    
    await db(this.TABLE)
      .where({ id: payment.id })
      .update({
        status,
        updatedAt: new Date()
      });
    
    return await this.getPaymentById(payment.id);
  }

  static async listPayments(tenantId: string, filters?: any): Promise<Payment[]> {
    let query = db(this.TABLE).where({ tenantId });
    
    if (filters) {
      if (filters.status) query = query.where({ status: filters.status });
      if (filters.startDate) query = query.where('createdAt', '>=', filters.startDate);
      if (filters.endDate) query = query.where('createdAt', '<=', filters.endDate);
    }
    
    return await query.orderBy('createdAt', 'desc');
  }
}
