import { pool } from './db';

export interface PaymentSettingsRow {
  loading_message: string;
  fee_notice: string;
  sham_cash_enabled: boolean;
  sham_cash_currency: string;
  sham_cash_fees: Record<string, string>;
  sham_cash_qr_encrypted: string | null;
  sham_cash_qr_mime: string | null;
  paypal_enabled: boolean;
  paypal_currency: string;
  paypal_fees: Record<string, string>;
  admin_work_timezone: string;
  admin_work_days: number[];
  admin_work_start_minutes: number;
  admin_work_end_minutes: number;
  sham_cash_review_minutes: number;
  sham_cash_after_open_minutes: number;
  updated_at: Date;
}

export const readPaymentSettings = async (): Promise<PaymentSettingsRow> => {
  const result = await pool.query<PaymentSettingsRow>('SELECT * FROM platform_settings WHERE singleton=TRUE');
  if (!result.rows[0]) throw new Error('Platform settings are unavailable');
  return result.rows[0];
};

export const feeFor = (
  settings: PaymentSettingsRow,
  method: 'sham_cash' | 'paypal',
  sessionNumber: number,
): { amount: string; currency: string } => {
  const fees = method === 'sham_cash' ? settings.sham_cash_fees : settings.paypal_fees;
  const currency = method === 'sham_cash' ? settings.sham_cash_currency : settings.paypal_currency;
  const amount = Number(fees[String(sessionNumber)] ?? 0).toFixed(2);
  return { amount, currency };
};

export const ensurePaymentObligations = async (meetingId: string): Promise<void> => {
  await pool.query(
    `INSERT INTO meeting_payment_obligations (meeting_id, beneficiary_user_id)
     SELECT meeting.id, participant.user_id
     FROM meeting_proposals meeting
     JOIN journeys journey ON journey.id=meeting.journey_id
     CROSS JOIN LATERAL (VALUES (journey.first_user_id),(journey.second_user_id)) participant(user_id)
     WHERE meeting.id=$1 AND meeting.status IN ('confirmed','completed')
     ON CONFLICT (meeting_id, beneficiary_user_id) DO NOTHING`,
    [meetingId],
  );
  await pool.query(
    `UPDATE meeting_payment_obligations payment SET status='pending',updated_at=NOW()
     WHERE payment.meeting_id=$1 AND payment.status='waived'
       AND NOT EXISTS (
         SELECT 1 FROM meeting_payment_obligations completed
         WHERE completed.meeting_id=payment.meeting_id AND completed.status='paid'
       )`,
    [meetingId],
  );
};

export const meetingPaymentsReady = async (meetingId: string | null): Promise<boolean> => {
  if (!meetingId) return false;
  await ensurePaymentObligations(meetingId);
  const result = await pool.query<{ paid: number }>(
    `SELECT COUNT(*) FILTER (WHERE status='paid')::int AS paid
     FROM meeting_payment_obligations WHERE meeting_id=$1`,
    [meetingId],
  );
  return (result.rows[0]?.paid ?? 0) > 0;
};
