<%
'=======================================================================================================================
' Orders Repository
'=======================================================================================================================
Class OrdersRepository_Class

    ' Creates a new order row for the given email/jurisdiction, generates a single-use
    ' token that expires after OrderTokenExpirationHours, and returns that token.
    Public Function CreateOrder(email, jurisdictionNumber)
        Dim token, expiresAt
        token = NewGuid()
        expiresAt = DateAdd("h", TokenExpirationHours(), Now())

        DAL.Execute _
            "INSERT INTO Orders (Email, JurisdictionNumber, Token, TokenExpiresAt, CreatedAt) VALUES (?, ?, ?, ?, ?)", _
            Array(email, jurisdictionNumber, token, expiresAt, Now())

        CreateOrder = token
    End Function

    ' Returns a Scripting.Dictionary of Scripting.Dictionary rows for every order, newest first.
    Public Function GetAll()
        Dim rs, results, order
        Set results = Server.CreateObject("Scripting.Dictionary")

        Set rs = DAL.Query( _
            "SELECT OrderID, Email, JurisdictionNumber, Token, TokenExpiresAt, TokenUsedAt, CreatedAt FROM Orders ORDER BY OrderID DESC", _
            Empty)

        Do While Not rs.EOF
            Set order = Server.CreateObject("Scripting.Dictionary")
            order.Add "OrderID", rs("OrderID").Value
            order.Add "Email", rs("Email").Value
            order.Add "JurisdictionNumber", rs("JurisdictionNumber").Value
            order.Add "Token", rs("Token").Value
            order.Add "TokenExpiresAt", rs("TokenExpiresAt").Value
            order.Add "TokenUsedAt", rs("TokenUsedAt").Value
            order.Add "CreatedAt", rs("CreatedAt").Value
            results.Add rs("OrderID").Value, order
            rs.MoveNext
        Loop

        Destroy rs
        Set GetAll = results
    End Function

    ' Returns a Scripting.Dictionary of Scripting.Dictionary rows (newest first) matching searchTerm
    ' against Email or JurisdictionNumber (all rows if searchTerm is blank), one page at a time.
    ' page_count/record_count are returned by reference for building pagination controls.
    Public Function SearchPaged(searchTerm, per_page, page_num, ByRef page_count, ByRef record_count)
        Dim sql, params
        sql = "SELECT OrderID, Email, JurisdictionNumber, Token, TokenExpiresAt, TokenUsedAt, CreatedAt FROM Orders"
        page_count = 0
        record_count = 0

        If Len(Trim(searchTerm)) > 0 Then
            sql = sql & " WHERE Email LIKE ? OR JurisdictionNumber LIKE ?"
            params = Array("%" & searchTerm & "%", "%" & searchTerm & "%")
        Else
            params = Empty
        End If

        sql = sql & " ORDER BY OrderID DESC"

        Dim rs : Set rs = DAL.PagedQuery(sql, params, per_page, page_num)

        If Not rs.EOF Then
            rs.PageSize     = per_page
            rs.AbsolutePage = page_num
            page_count      = rs.PageCount
            record_count    = rs.RecordCount
        End If

        Dim results, order, x
        Set results = Server.CreateObject("Scripting.Dictionary")
        x = 0
        Do While (per_page <= 0 Or x < per_page) And Not rs.EOF
            Set order = Server.CreateObject("Scripting.Dictionary")
            order.Add "OrderID", rs("OrderID").Value
            order.Add "Email", rs("Email").Value
            order.Add "JurisdictionNumber", rs("JurisdictionNumber").Value
            order.Add "Token", rs("Token").Value
            order.Add "TokenExpiresAt", rs("TokenExpiresAt").Value
            order.Add "TokenUsedAt", rs("TokenUsedAt").Value
            order.Add "CreatedAt", rs("CreatedAt").Value
            results.Add rs("OrderID").Value, order
            x = x + 1
            rs.MoveNext
        Loop

        Destroy rs
        Set SearchPaged = results
    End Function

    ' Returns a Scripting.Dictionary describing the order matching the given token, or Nothing if not found.
    Public Function FindByToken(token)
        Dim rs
        Set rs = DAL.Query( _
            "SELECT OrderID, Email, JurisdictionNumber, Token, TokenExpiresAt, TokenUsedAt, CreatedAt FROM Orders WHERE Token = ?", _
            Array(token))

        If rs.EOF Then
            Set FindByToken = Nothing
        Else
            Dim order : Set order = Server.CreateObject("Scripting.Dictionary")
            order.Add "OrderID", rs("OrderID").Value
            order.Add "Email", rs("Email").Value
            order.Add "JurisdictionNumber", rs("JurisdictionNumber").Value
            order.Add "Token", rs("Token").Value
            order.Add "TokenExpiresAt", rs("TokenExpiresAt").Value
            order.Add "TokenUsedAt", rs("TokenUsedAt").Value
            order.Add "CreatedAt", rs("CreatedAt").Value
            Set FindByToken = order
        End If

        Destroy rs
    End Function

    Public Sub MarkTokenUsed(orderId)
        DAL.Execute "UPDATE Orders SET TokenUsedAt = ? WHERE OrderID = ?", Array(Now(), orderId)
    End Sub

    Private Function TokenExpirationHours()
        Dim setting : setting = GetAppSetting("OrderTokenExpirationHours")
        If setting = "nothing" Or Not IsNumeric(setting) Then
            TokenExpirationHours = 24
        Else
            TokenExpirationHours = CInt(setting)
        End If
    End Function

End Class

Dim OrdersRepository__Singleton
Function OrdersRepository()
    If IsEmpty(OrdersRepository__Singleton) Then
        Set OrdersRepository__Singleton = New OrdersRepository_Class
    End If
    Set OrdersRepository = OrdersRepository__Singleton
End Function
%>
