/**
 * Per-record offer/contract conditions persistence.
 * The last-sent quote and contract conditions are stored as ONE JSON blob in the
 * custom column `offer_conditions` (Text) on AD_User (leads) / C_BPartner
 * (partners): { quote: {...}, contract: {...} } — each section stamped with
 * `savedAt`. Written on every successful send, read on every modal open, and
 * copied lead → partner by merchant onboarding.
 *
 * All readers/writers are FAIL-SOFT: a missing column (not yet created in
 * iDempiere) or malformed JSON degrades to "no saved conditions" and must never
 * break the send/onboarding flows.
 */
import fetchHelper from '../fetchHelper'

const modelFor = (source: string): string => (source === 'lead' ? 'ad_user' : 'c_bpartner')

export const readOfferConditions = async (event: any, token: string, source: string, recordId: number): Promise<any> => {
  let res: any = null
  try {
    res = await fetchHelper(event, `models/${modelFor(source)}/${recordId}`, 'GET', token, null)
  } catch (e: any) {
    const s = Number(e?.statusCode ?? e?.status ?? e?.response?.status)
    if (s === 401) throw e // let callers run the token-refresh path
    return {}
  }
  try {
    const raw = res?.offer_conditions ?? res?.Offer_Conditions ?? ''
    if (!raw || String(raw).trim() === '') return {}
    const parsed = JSON.parse(String(raw))
    return parsed && typeof parsed === 'object' ? parsed : {}
  } catch {
    return {}
  }
}

/** Read-merge-write so the quote and contract sections never clobber each other. */
export const saveOfferConditions = async (
  event: any,
  token: string,
  source: string,
  recordId: number,
  docType: 'quote' | 'contract',
  conditions: any
): Promise<void> => {
  const current = await readOfferConditions(event, token, source, recordId)
  const merged = { ...current, [docType]: { ...conditions, savedAt: new Date().toISOString() } }
  await fetchHelper(event, `models/${modelFor(source)}/${recordId}`, 'PUT', token, {
    offer_conditions: JSON.stringify(merged)
  })
}

/** Extract the persistable conditions from a quote send payload (email etc. stripped). */
export const conditionsFromQuotePayload = (p: any) => ({
  language: p?.meta?.language === 'en' ? 'en' : 'de',
  customer: p?.customer || {},
  assumptions: p?.assumptions || {},
  pricing: p?.pricing || {},
  inbound: p?.inbound || {},
  services: p?.services || {},
  customPositions: Array.isArray(p?.customPositions) ? p.customPositions : [],
  sections: p?.sections && typeof p.sections === 'object' ? p.sections : {},
  customTexts: Array.isArray(p?.customTexts) ? p.customTexts : [],
  volumeMatrix: p?.volumeMatrix || {},
  validDays: Number(p?.meta?.validDays) || 7,
  confirmation: { enabled: p?.confirmation?.enabled !== false, attachPdf: p?.confirmation?.attachPdf === true }
})

/** Extract the persistable conditions from a contract send payload. */
export const conditionsFromContractPayload = (p: any) => ({
  language: p?.meta?.language === 'en' ? 'en' : 'de',
  customer: p?.customer || {},
  assumptions: p?.assumptions || {},
  contract: p?.contract || {},                      // incl. `sections` (deselected parts)
  attachments: p?.attachments && typeof p.attachments === 'object' ? p.attachments : {},
  signing: p?.signing && typeof p.signing === 'object'
    ? { enabled: p.signing.enabled !== false, expiryDays: Number(p.signing.expiryDays) || 7, attachDocuments: p.signing.attachDocuments === true }
    : {}
})

/**
 * Merge a partial patch into ONE section (e.g. `contract.signature = {...}`)
 * without touching the section's other keys or its `savedAt`. Used by the
 * public signing flow, which must not look like a "new send".
 */
export const patchOfferConditionsSection = async (
  event: any,
  token: string,
  source: string,
  recordId: number,
  docType: 'quote' | 'contract',
  patch: any
): Promise<void> => {
  const current = await readOfferConditions(event, token, source, recordId)
  const merged = { ...current, [docType]: { ...(current?.[docType] || {}), ...patch } }
  await fetchHelper(event, `models/${modelFor(source)}/${recordId}`, 'PUT', token, {
    offer_conditions: JSON.stringify(merged)
  })
}
