import { parse_extkey } from '@cmdcode/crypto-tools/hd';
import { validate_deposit } from '../validators/deposit.js';
import { get_return_script } from './return.js';
import { get_object_id, sort_record } from './util.js';
import { get_key_ctx, tweak_key_ctx } from '@cmdcode/musig2';
import { create_tx_template, get_address, get_tapkey, parse_timelock } from './tx.js';
const GET_INIT_SPEND_STATE = () => {
    return {
        confirmed: false,
        block_hash: null,
        block_height: null,
        block_time: null,
        expires_at: null,
    };
};
const GET_INIT_DEPOSIT = () => {
    return {
        ...GET_INIT_SPEND_STATE(),
        covenant: null,
        return_psig: null,
        settled: false,
        settled_at: null,
        spent: false,
        spent_at: null,
        spent_txid: null,
        status: 'pending'
    };
};
export function create_deposit(created_at, request, session, state) {
    const { utxo, ...rest } = request;
    const dpid = get_deposit_id(created_at, request);
    const updated_at = created_at;
    const template = { ...GET_INIT_DEPOSIT(), ...rest, ...session, ...state, ...utxo };
    const deposit = { ...template, dpid, created_at, updated_at };
    if (deposit.confirmed) {
        if (deposit.covenant !== null) {
            deposit.status = 'locked';
        }
        else {
            deposit.status = 'open';
        }
    }
    validate_deposit(deposit);
    return sort_record(deposit);
}
export function get_deposit_ctx(agent_pk, deposit_pk, return_pk, sequence) {
    const members = [agent_pk, deposit_pk];
    const script = get_return_script(return_pk, sequence);
    const int_data = get_key_ctx(members);
    const tap_data = get_tapkey(int_data.group_pubkey.hex, script);
    const key_data = tweak_key_ctx(int_data, [tap_data.taptweak]);
    return { agent_pk, deposit_pk, return_pk, sequence, script, tap_data, key_data };
}
export function get_deposit_id(created_at, request) {
    const { deposit_pk, sequence, spend_xpub, utxo } = request;
    const preimg = { created_at, deposit_pk, sequence, spend_xpub, utxo };
    return get_object_id(preimg).hex;
}
export function get_deposit_address(context, network) {
    const { tap_data } = context;
    return get_address(tap_data.tapkey, network);
}
export function get_spend_state(sequence, txstatus) {
    let state = GET_INIT_SPEND_STATE();
    if (txstatus !== undefined && txstatus.confirmed) {
        const timelock = parse_timelock(sequence);
        const expires_at = txstatus.block_time + timelock;
        state = { ...txstatus, expires_at };
    }
    return state;
}
export function get_ext_pubkey(xpub) {
    return parse_extkey(xpub).pubkey;
}
export function get_close_tx_template(txfee, value, xpub) {
    const return_pk = get_ext_pubkey(xpub);
    const script = ['OP_1', return_pk];
    return create_tx_template(script, value - txfee);
}
