import argon2 from 'argon2';
import { z } from 'zod';

export default class Member  {
    prefix = "MEMBER"
    indices = null

    constructor(indices) {
        this.indices = indices
    }

    addressSchema = z.object({
        address1: z.string(),
        address2: z.string().optional(),
        zip: z.string().regex(/^\d{5}(-\d{4})?$/),
        state: z.string(),
        city: z.string()
    })
    schema = z.object({
        id: z.number(),
        email: z.string().email(),
        firstName: z.string(),
        lastName: z.string(),
        password: z.string(),
        joined: z.string(),
        address: this.addressSchema.optional()
    })

    isHashed = (s) => {return s.startsWith("$argon2")}

    save(member) {
        let id = `${this.prefix}-${member.id}`
        let result = this.schema.safeParse(member)
        if(result.success) {
            try {
                global.db.addNode(id, member)
            } catch(e) {
                console.error(e)
                throw e
            }
        } else {
            console.error("Failed parsing member: ", result.error)
            throw new global.ServerError(400, "Invalid Member Data!: ");
        }
    }

    async add(newMember) {
        const hash = await argon2.hash(newMember.password);
        newMember.password = hash
        newMember.joined = global.currentTime()
        newMember.id = this.indices[1] - 1
        this.save(newMember)
    }

    get(id) {
        return this.entries[this.ids[id]]
    }

    getByEmail(email) {
        for(let i=this.indices[0]; i<this.indices[1]; i++) {
            if(global.db.nodes[i].email === email) {
                return global.db.nodes[i]
            }
        }
        return null
    }

    getIDFromEmail(email) {
        let index = 0
        for(let i=0; i<this.entries.length; i++) {
            if(this.entries[i].email === email) {
                index = i
                break
            }
        }
        return Object.entries(this.ids)[index][0]
    }
}