type account = {
  name : LString.t;
  account_type : LString.t;
  currency : int;
  asset_type : int;
  account_number : LString.t;
  balance : real;
}

type balance_sheet_report = {
  ledger : ledger;
  tgt_currency : int;
}

and ledger = {
  assets : account list;
  liabilities : account list;
}

let currency_usd = 1
let account_asset = 1

let currency_pairs_convert : int -> int -> real -> real = () [@@opaque]

let create_account name account_type currency asset_type account_number balance =
  { name = name; account_type = account_type; currency = currency; 
    asset_type = asset_type; account_number = account_number; balance = balance }

let create_balance_sheet_report ledger tgt_currency =
  { ledger = ledger; tgt_currency = tgt_currency }

let convert_account_to_usd account =
  if account.currency = currency_usd then
    account.balance
  else
    currency_pairs_convert account.currency currency_usd account.balance

let generate_report report =
  let convert_account = convert_account_to_usd in
  let total_assets = List.fold_left (fun acc asset -> acc +. convert_account asset) 0.0 report.ledger.assets in
  let total_liabilities = List.fold_left (fun acc liability -> acc +. convert_account liability) 0.0 report.ledger.liabilities in
  let net_assets = total_assets -. total_liabilities in
  (total_assets, total_liabilities, net_assets)

let create_ledger assets liabilities =
  { assets = assets; liabilities = liabilities }

let gen_report ledger =
  let report = create_balance_sheet_report ledger currency_usd in
  generate_report report

let create_sample_data () =
  let a = [] in
  let l = [] in
  
  let l = create_account {l|John Doe|l} {l|Savings Account|l} currency_usd account_asset {l|123456789|l} 1000.0 :: l in
  let l = create_account {l|Jane Doe|l} {l|Checking Account|l} currency_usd account_asset {l|987654321|l} 1500.0 :: l in
  let l = create_account {l|John Doe|l} {l|Savings Account|l} currency_usd account_asset {l|123456789|l} 1000.0 :: l in
  let l = create_account {l|Jane Doe|l} {l|Checking Account|l} currency_usd account_asset {l|987654321|l} 1500.0 :: l in
  let l = create_account {l|John Doe|l} {l|Savings Account|l} currency_usd account_asset {l|123456789|l} 1000.0 :: l in
  let l = create_account {l|Jane Doe|l} {l|Checking Account|l} currency_usd account_asset {l|987654321|l} 1500.0 :: l in
  
  let a = create_account {l|Jane Doe|l} {l|Checking Account|l} currency_usd account_asset {l|987654321|l} 1500.0 :: a in
  let a = create_account {l|John Doe|l} {l|Savings Account|l} currency_usd account_asset {l|123456789|l} 1000.0 :: a in
  let a = create_account {l|Jane Doe|l} {l|Checking Account|l} currency_usd account_asset {l|987654321|l} 1500.0 :: a in
  let a = create_account {l|John Doe|l} {l|Savings Account|l} currency_usd account_asset {l|123456789|l} 1000.0 :: a in
  let a = create_account {l|Jane Doe|l} {l|Checking Account|l} currency_usd account_asset {l|987654321|l} 1500.0 :: a in
  let a = create_account {l|John Doe|l} {l|Savings Account|l} currency_usd account_asset {l|123456789|l} 1000.0 :: a in
  
  (a, l)

let main () =
  let a, l = create_sample_data () in
  let ledger = create_ledger a l in
  let report = create_balance_sheet_report ledger currency_usd in
  generate_report report
