import { getDb } from '../db/client.js'
import { ExtensionTimeoutAction } from '../constants.js'

const sql = getDb()

export const getAnonymityConfig = async () => {
  const [row] = await sql`SELECT value FROM app_config WHERE key = 'anonymity'`
  return { anonymity_enabled: row?.value?.enabled ?? false }
}

export const setAnonymityConfig = async (enabled) => {
  await sql`
    INSERT INTO app_config (key, value, updated_at)
    VALUES ('anonymity', ${sql.json({ enabled })}, NOW())
    ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
  `
  return { anonymity_enabled: enabled }
}

export const getMaxCustomersPerMitra = async () => {
  const [row] = await sql`SELECT value FROM app_config WHERE key = 'max_customers_per_mitra'`
  return { max_customers_per_mitra: row?.value?.value ?? 3 }
}

export const setMaxCustomersPerMitra = async (value) => {
  await sql`
    INSERT INTO app_config (key, value, updated_at)
    VALUES ('max_customers_per_mitra', ${sql.json({ value })}, NOW())
    ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
  `
  // Capacity changed → drop cached availability snapshot.
  // Imported lazily to avoid a circular import (mitra-status.service uses config).
  const { invalidateAvailabilityCache } = await import('./mitra-status.service.js')
  invalidateAvailabilityCache()
  return { max_customers_per_mitra: value }
}

// --- Phase 4: First-session discount (replaces Phase 3 free-trial config) ---

export const getFirstSessionDiscountConfig = async () => {
  const rows = await sql`
    SELECT key, value FROM app_config
    WHERE key IN (
      'first_session_discount_enabled',
      'first_session_discount_actual_price_idr',
      'first_session_discount_gimmick_price_idr',
      'first_session_discount_duration_minutes',
      'first_session_discount_modes'
    )
  `
  const byKey = Object.fromEntries(rows.map((r) => [r.key, r.value?.value]))
  return {
    enabled: byKey.first_session_discount_enabled ?? true,
    actual_price_idr: byKey.first_session_discount_actual_price_idr ?? 2000,
    gimmick_price_idr: byKey.first_session_discount_gimmick_price_idr ?? 12000,
    duration_minutes: byKey.first_session_discount_duration_minutes ?? 12,
    modes: byKey.first_session_discount_modes ?? ['chat'],
  }
}

export const setFirstSessionDiscountConfig = async (patch) => {
  const map = {
    enabled: 'first_session_discount_enabled',
    actual_price_idr: 'first_session_discount_actual_price_idr',
    gimmick_price_idr: 'first_session_discount_gimmick_price_idr',
    duration_minutes: 'first_session_discount_duration_minutes',
    modes: 'first_session_discount_modes',
  }
  for (const [field, key] of Object.entries(map)) {
    if (patch[field] === undefined) continue
    await sql`
      INSERT INTO app_config (key, value, updated_at)
      VALUES (${key}, ${sql.json({ value: patch[field] })}, NOW())
      ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
    `
  }
  return getFirstSessionDiscountConfig()
}

// Back-compat shim — CC settings page still calls /internal/config/free-trial.
// Phase 4 routes will be added; until the CC UI is migrated this maps to the new keys.
export const getFreeTrialConfig = async () => {
  const cfg = await getFirstSessionDiscountConfig()
  return {
    enabled: cfg.enabled,
    duration_minutes: cfg.duration_minutes,
  }
}

export const setFreeTrialConfig = async ({ enabled, duration_minutes }) => {
  return setFirstSessionDiscountConfig({
    ...(enabled !== undefined ? { enabled } : {}),
    ...(duration_minutes !== undefined ? { duration_minutes } : {}),
  })
}

// --- Phase 4: Support handles ---

export const getSupportHandles = async () => {
  const [row] = await sql`SELECT value FROM app_config WHERE key = 'support_handles_json'`
  // Stored shape: { wa: {...}, telegram: {...} }. Fall back to a safe empty payload
  // so the client renders an empty Tanya Admin sheet rather than crashing.
  return row?.value ?? {
    wa: { label: 'WhatsApp', deeplink: '' },
    telegram: { label: 'Telegram', deeplink: '' },
  }
}

export const setSupportHandles = async ({ wa, telegram }) => {
  const current = await getSupportHandles()
  const next = {
    wa: { ...current.wa, ...(wa || {}) },
    telegram: { ...current.telegram, ...(telegram || {}) },
  }
  await sql`
    INSERT INTO app_config (key, value, updated_at)
    VALUES ('support_handles_json', ${sql.json(next)}, NOW())
    ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
  `
  return next
}

// --- Phase 4: Pricing tier groups ---

export const getPricingTierGroups = async () => {
  const rows = await sql`
    SELECT key, value FROM app_config
    WHERE key IN ('pricing_chat_tiers_json', 'pricing_call_tiers_json')
  `
  const byKey = Object.fromEntries(rows.map((r) => [r.key, r.value]))
  return {
    chat: byKey.pricing_chat_tiers_json?.tiers ?? [],
    call: byKey.pricing_call_tiers_json?.tiers ?? [],
  }
}

export const setPricingTierGroup = async (mode, tiers) => {
  const key = mode === 'call' ? 'pricing_call_tiers_json' : 'pricing_chat_tiers_json'
  await sql`
    INSERT INTO app_config (key, value, updated_at)
    VALUES (${key}, ${sql.json({ tiers })}, NOW())
    ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
  `
  return getPricingTierGroups()
}

export const getExtensionTimeoutConfig = async () => {
  const [row] = await sql`SELECT value FROM app_config WHERE key = 'extension_timeout_seconds'`
  // Default 10s pairs with the auto-approve-on-timeout flow; raise this if you change the policy to auto-reject.
  return { extension_timeout_seconds: row?.value?.value ?? 10 }
}

export const setExtensionTimeoutConfig = async (seconds) => {
  await sql`
    INSERT INTO app_config (key, value, updated_at)
    VALUES ('extension_timeout_seconds', ${sql.json({ value: seconds })}, NOW())
    ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
  `
  return { extension_timeout_seconds: seconds }
}

export const getEarlyEndConfig = async () => {
  const [mitraRow] = await sql`SELECT value FROM app_config WHERE key = 'early_end_mitra_enabled'`
  const [customerRow] = await sql`SELECT value FROM app_config WHERE key = 'early_end_customer_enabled'`
  return {
    mitra_enabled: mitraRow?.value?.value ?? false,
    customer_enabled: customerRow?.value?.value ?? false,
  }
}

// --- Phase 3.1: Mitra Ping Config ---

export const getMitraPingConfig = async () => {
  const [requireRow] = await sql`SELECT value FROM app_config WHERE key = 'require_mitra_ping'`
  const [intervalRow] = await sql`SELECT value FROM app_config WHERE key = 'mitra_ping_interval_seconds'`
  return {
    require_ping: requireRow?.value?.value ?? true,
    ping_interval_seconds: intervalRow?.value?.value ?? 15,
  }
}

export const setMitraPingConfig = async ({ require_ping, ping_interval_seconds }) => {
  if (require_ping !== undefined) {
    await sql`
      INSERT INTO app_config (key, value, updated_at)
      VALUES ('require_mitra_ping', ${sql.json({ value: require_ping })}, NOW())
      ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
    `
  }
  if (ping_interval_seconds !== undefined) {
    await sql`
      INSERT INTO app_config (key, value, updated_at)
      VALUES ('mitra_ping_interval_seconds', ${sql.json({ value: ping_interval_seconds })}, NOW())
      ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
    `
  }
  return getMitraPingConfig()
}

export const setEarlyEndConfig = async ({ mitra_enabled, customer_enabled }) => {
  if (mitra_enabled !== undefined) {
    await sql`
      INSERT INTO app_config (key, value, updated_at)
      VALUES ('early_end_mitra_enabled', ${sql.json({ value: mitra_enabled })}, NOW())
      ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
    `
  }
  if (customer_enabled !== undefined) {
    await sql`
      INSERT INTO app_config (key, value, updated_at)
      VALUES ('early_end_customer_enabled', ${sql.json({ value: customer_enabled })}, NOW())
      ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
    `
  }
  return getEarlyEndConfig()
}

// --- Phase 3.3: Session Topic Sensitivity ---

export const getSensitivityConfig = async () => {
  const [confirmRow] = await sql`SELECT value FROM app_config WHERE key = 'sensitive_flip_confirmation_enabled'`
  const [latchRow] = await sql`SELECT value FROM app_config WHERE key = 'sensitive_flag_one_way_latch'`
  return {
    flip_confirmation_enabled: confirmRow?.value?.value ?? true,
    one_way_latch: latchRow?.value?.value ?? false,
  }
}

export const setSensitivityConfig = async ({ flip_confirmation_enabled, one_way_latch }) => {
  if (flip_confirmation_enabled !== undefined) {
    await sql`
      INSERT INTO app_config (key, value, updated_at)
      VALUES ('sensitive_flip_confirmation_enabled', ${sql.json({ value: flip_confirmation_enabled })}, NOW())
      ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
    `
  }
  if (one_way_latch !== undefined) {
    await sql`
      INSERT INTO app_config (key, value, updated_at)
      VALUES ('sensitive_flag_one_way_latch', ${sql.json({ value: one_way_latch })}, NOW())
      ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
    `
  }
  return getSensitivityConfig()
}

// --- Phase 3.4: Self-Managed Auth ---

export const getOtpRateLimits = async () => {
  const [phoneRow] = await sql`SELECT value FROM app_config WHERE key = 'otp_max_per_phone_per_hour'`
  const [ipRow] = await sql`SELECT value FROM app_config WHERE key = 'otp_max_per_ip_per_hour'`
  const [resendRow] = await sql`SELECT value FROM app_config WHERE key = 'otp_resend_cooldown_seconds'`
  const [attemptsRow] = await sql`SELECT value FROM app_config WHERE key = 'otp_verify_max_attempts'`
  return {
    max_per_phone_per_hour: phoneRow?.value?.value ?? 3,
    max_per_ip_per_hour: ipRow?.value?.value ?? 10,
    resend_cooldown_seconds: resendRow?.value?.value ?? 60,
    verify_max_attempts: attemptsRow?.value?.value ?? 5,
  }
}

export const setOtpRateLimits = async ({
  max_per_phone_per_hour,
  max_per_ip_per_hour,
  resend_cooldown_seconds,
  verify_max_attempts,
}) => {
  const pairs = [
    ['otp_max_per_phone_per_hour', max_per_phone_per_hour],
    ['otp_max_per_ip_per_hour', max_per_ip_per_hour],
    ['otp_resend_cooldown_seconds', resend_cooldown_seconds],
    ['otp_verify_max_attempts', verify_max_attempts],
  ]
  for (const [key, value] of pairs) {
    if (value === undefined) continue
    await sql`
      INSERT INTO app_config (key, value, updated_at)
      VALUES (${key}, ${sql.json({ value })}, NOW())
      ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
    `
  }
  return getOtpRateLimits()
}

export const getCcLoginLockoutConfig = async () => {
  const [attemptsRow] = await sql`SELECT value FROM app_config WHERE key = 'cc_login_max_attempts'`
  const [minutesRow] = await sql`SELECT value FROM app_config WHERE key = 'cc_login_lockout_minutes'`
  return {
    max_attempts: attemptsRow?.value?.value ?? 5,
    lockout_minutes: minutesRow?.value?.value ?? 15,
  }
}

export const setCcLoginLockoutConfig = async ({ max_attempts, lockout_minutes }) => {
  if (max_attempts !== undefined) {
    await sql`
      INSERT INTO app_config (key, value, updated_at)
      VALUES ('cc_login_max_attempts', ${sql.json({ value: max_attempts })}, NOW())
      ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
    `
  }
  if (lockout_minutes !== undefined) {
    await sql`
      INSERT INTO app_config (key, value, updated_at)
      VALUES ('cc_login_lockout_minutes', ${sql.json({ value: lockout_minutes })}, NOW())
      ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
    `
  }
  return getCcLoginLockoutConfig()
}

// --- Paid Pairing Flow + Returning-Chat + Extension Flip ---

export const getPaymentSessionTimeoutMinutes = async () => {
  const [row] = await sql`SELECT value FROM app_config WHERE key = 'payment_session_timeout_minutes'`
  return { payment_session_timeout_minutes: row?.value?.value ?? 20 }
}

export const setPaymentSessionTimeoutMinutes = async (value) => {
  await sql`
    INSERT INTO app_config (key, value, updated_at)
    VALUES ('payment_session_timeout_minutes', ${sql.json({ value })}, NOW())
    ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
  `
  return { payment_session_timeout_minutes: value }
}

export const getReturningChatConfirmationTimeoutSeconds = async () => {
  const [row] = await sql`SELECT value FROM app_config WHERE key = 'returning_chat_confirmation_timeout_seconds'`
  return { returning_chat_confirmation_timeout_seconds: row?.value?.value ?? 20 }
}

export const setReturningChatConfirmationTimeoutSeconds = async (value) => {
  await sql`
    INSERT INTO app_config (key, value, updated_at)
    VALUES ('returning_chat_confirmation_timeout_seconds', ${sql.json({ value })}, NOW())
    ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
  `
  return { returning_chat_confirmation_timeout_seconds: value }
}

export const getExtensionDefaultActionOnTimeout = async () => {
  const [row] = await sql`SELECT value FROM app_config WHERE key = 'extension_default_action_on_timeout'`
  return { extension_default_action_on_timeout: row?.value?.value ?? ExtensionTimeoutAction.AUTO_APPROVE }
}

export const setExtensionDefaultActionOnTimeout = async (value) => {
  await sql`
    INSERT INTO app_config (key, value, updated_at)
    VALUES ('extension_default_action_on_timeout', ${sql.json({ value })}, NOW())
    ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
  `
  return { extension_default_action_on_timeout: value }
}

export const getPairingBlastTimeoutSeconds = async () => {
  const [row] = await sql`SELECT value FROM app_config WHERE key = 'pairing_blast_timeout_seconds'`
  return { pairing_blast_timeout_seconds: row?.value?.value ?? 60 }
}

export const setPairingBlastTimeoutSeconds = async (value) => {
  await sql`
    INSERT INTO app_config (key, value, updated_at)
    VALUES ('pairing_blast_timeout_seconds', ${sql.json({ value })}, NOW())
    ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()
  `
  return { pairing_blast_timeout_seconds: value }
}
