-- Loan statement support.
--
-- Migration 0013 taught the system that a statement can be a loan; this gives
-- loans somewhere to put the data that only loans have.
--
-- The core accounting problem: a loan repayment is not an expense. A $3,000
-- mortgage repayment is roughly $1,200 of principal (a balance-sheet move that
-- builds equity) and $1,800 of interest (the only part that is genuinely spend).
-- Counting the whole repayment as spending overstates expenses badly.
--
-- Two statement shapes are handled:
--   (a) The common Australian case — the loan statement lists repayments and
--       "Interest Charged" as separate rows. transaction_type already carries
--       this: 'interest' rows count as spend, 'payment' rows do not.
--   (b) Some lenders itemise principal and interest on the repayment row itself.
--       That's what principal_amount / interest_amount are for: when
--       interest_amount is set, analytics count that instead of the full amount.
--
-- Idempotent: safe to re-run.

-- Per-transaction principal/interest split (shape (b) above).
ALTER TABLE transactions
  ADD COLUMN IF NOT EXISTS principal_amount NUMERIC(12,2),
  ADD COLUMN IF NOT EXISTS interest_amount  NUMERIC(12,2);

COMMENT ON COLUMN transactions.principal_amount IS
  'Principal portion of a loan repayment, when the statement itemises it. Not spend.';
COMMENT ON COLUMN transactions.interest_amount IS
  'Interest portion of a loan repayment, when the statement itemises it. This is the part that counts as spend.';

-- Partial index: only loan repayment rows carry a split.
CREATE INDEX IF NOT EXISTS idx_transactions_interest_amount
  ON transactions (interest_amount)
  WHERE interest_amount IS NOT NULL;

-- Loan-level terms, read off the statement header.
ALTER TABLE statements
  ADD COLUMN IF NOT EXISTS interest_rate        NUMERIC(6,3),
  ADD COLUMN IF NOT EXISTS scheduled_repayment  NUMERIC(12,2),
  ADD COLUMN IF NOT EXISTS repayment_frequency  TEXT,
  ADD COLUMN IF NOT EXISTS redraw_available     NUMERIC(12,2),
  ADD COLUMN IF NOT EXISTS loan_term_months     INTEGER;

COMMENT ON COLUMN statements.interest_rate IS 'Annual interest rate as a percentage, e.g. 6.140';
COMMENT ON COLUMN statements.redraw_available IS 'Funds available to redraw (loans) — not the same as available_credit on a card.';

-- Free text varies by lender ("Monthly", "Fortnightly"); normalise the common
-- spellings rather than constraining, so an unexpected value never blocks an import.
ALTER TABLE statements DROP CONSTRAINT IF EXISTS statements_repayment_frequency_check;

CREATE OR REPLACE FUNCTION normalize_repayment_frequency(raw TEXT)
RETURNS TEXT AS $$
DECLARE
  v TEXT := lower(trim(coalesce(raw, '')));
BEGIN
  IF v = '' THEN RETURN NULL; END IF;
  -- Check fortnightly spellings before the bare '%week%' match below.
  IF v LIKE '%fortnight%' OR v LIKE '%bi-week%' OR v LIKE '%biweek%'
     OR v LIKE '%2 week%' OR v LIKE '%two week%' OR v LIKE '%14 day%'
  THEN RETURN 'fortnightly'; END IF;
  IF v LIKE '%month%'   THEN RETURN 'monthly'; END IF;
  IF v LIKE '%week%'    THEN RETURN 'weekly'; END IF;
  IF v LIKE '%quarter%' THEN RETURN 'quarterly'; END IF;
  IF v LIKE '%annual%' OR v LIKE '%year%' THEN RETURN 'annually'; END IF;
  RETURN v;
END;
$$ LANGUAGE plpgsql IMMUTABLE;

CREATE OR REPLACE FUNCTION statements_normalize_loan_fields_trigger()
RETURNS TRIGGER AS $$
BEGIN
  NEW.repayment_frequency := normalize_repayment_frequency(NEW.repayment_frequency);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_statements_normalize_loan_fields ON statements;
CREATE TRIGGER trg_statements_normalize_loan_fields
  BEFORE INSERT OR UPDATE OF repayment_frequency ON statements
  FOR EACH ROW EXECUTE FUNCTION statements_normalize_loan_fields_trigger();

UPDATE statements
SET repayment_frequency = normalize_repayment_frequency(repayment_frequency)
WHERE repayment_frequency IS NOT NULL
  AND repayment_frequency IS DISTINCT FROM normalize_repayment_frequency(repayment_frequency);
