class PrescriptionStatus(object):
    """
    Prescription states and related information
    """

    AWAITING_RELEASE_READY = "0000"
    TO_BE_DISPENSED = "0001"
    WITH_DISPENSER = "0002"
    WITH_DISPENSER_ACTIVE = "0003"
    EXPIRED = "0004"
    CANCELLED = "0005"
    DISPENSED = "0006"
    NOT_DISPENSED = "0007"
    CLAIMED = "0008"
    NO_CLAIMED = "0009"
    REPEAT_DISPENSE_FUTURE_INSTANCE = "9000"
    FUTURE_DATED_PRESCRIPTION = "9001"
    PENDING_CANCELLATION = "9005"

    PRESCRIPTION_DISPLAY_LOOKUP = {}
    PRESCRIPTION_DISPLAY_LOOKUP[AWAITING_RELEASE_READY] = "Awaiting Release Ready"
    PRESCRIPTION_DISPLAY_LOOKUP[TO_BE_DISPENSED] = "To Be Dispensed"
    PRESCRIPTION_DISPLAY_LOOKUP[WITH_DISPENSER] = "With Dispenser"
    PRESCRIPTION_DISPLAY_LOOKUP[WITH_DISPENSER_ACTIVE] = "With Dispenser - Active"
    PRESCRIPTION_DISPLAY_LOOKUP[EXPIRED] = "Expired"
    PRESCRIPTION_DISPLAY_LOOKUP[CANCELLED] = "Cancelled"
    PRESCRIPTION_DISPLAY_LOOKUP[DISPENSED] = "Dispensed"
    PRESCRIPTION_DISPLAY_LOOKUP[NOT_DISPENSED] = "Not Dispensed"
    PRESCRIPTION_DISPLAY_LOOKUP[CLAIMED] = "Claimed"
    PRESCRIPTION_DISPLAY_LOOKUP[NO_CLAIMED] = "No-Claimed"
    PRESCRIPTION_DISPLAY_LOOKUP[REPEAT_DISPENSE_FUTURE_INSTANCE] = "Repeat Dispense future instance"
    PRESCRIPTION_DISPLAY_LOOKUP[FUTURE_DATED_PRESCRIPTION] = "Prescription future instance"
    PRESCRIPTION_DISPLAY_LOOKUP[PENDING_CANCELLATION] = "Cancelled future instance"

    CANCELLABLE_STATES = [
        AWAITING_RELEASE_READY,
        TO_BE_DISPENSED,
        REPEAT_DISPENSE_FUTURE_INSTANCE,
        FUTURE_DATED_PRESCRIPTION,
    ]

    WITH_DISPENSER_STATES = [WITH_DISPENSER, WITH_DISPENSER_ACTIVE]

    ACTIVE_STATES = [AWAITING_RELEASE_READY, TO_BE_DISPENSED, WITH_DISPENSER, WITH_DISPENSER_ACTIVE]

    FUTURE_STATES = [FUTURE_DATED_PRESCRIPTION, REPEAT_DISPENSE_FUTURE_INSTANCE]

    COMPLETED_STATES = [EXPIRED, CANCELLED, DISPENSED, NOT_DISPENSED, CLAIMED, NO_CLAIMED]

    NOT_COMPLETED_STATES = [
        AWAITING_RELEASE_READY,
        TO_BE_DISPENSED,
        WITH_DISPENSER,
        WITH_DISPENSER_ACTIVE,
        FUTURE_DATED_PRESCRIPTION,
        REPEAT_DISPENSE_FUTURE_INSTANCE,
    ]

    INCLUDE_PERFORMER_STATES = [
        WITH_DISPENSER,
        WITH_DISPENSER_ACTIVE,
        DISPENSED,
        NOT_DISPENSED,
        CLAIMED,
        NO_CLAIMED,
    ]

    EXPIRY_IMMUTABLE_STATES = [EXPIRED, CANCELLED, DISPENSED, NOT_DISPENSED, CLAIMED, NO_CLAIMED]

    UNACTIONED_STATES = [
        AWAITING_RELEASE_READY,
        TO_BE_DISPENSED,
        WITH_DISPENSER,
        REPEAT_DISPENSE_FUTURE_INSTANCE,
        PENDING_CANCELLATION,
    ]

    ALL_VALID_STATES = [
        AWAITING_RELEASE_READY,
        TO_BE_DISPENSED,
        WITH_DISPENSER,
        WITH_DISPENSER_ACTIVE,
        EXPIRED,
        CANCELLED,
        DISPENSED,
        NOT_DISPENSED,
        CLAIMED,
        NO_CLAIMED,
        REPEAT_DISPENSE_FUTURE_INSTANCE,
        FUTURE_DATED_PRESCRIPTION,
        PENDING_CANCELLATION,
    ]

    EXPIRY_LOOKUP = {}
    EXPIRY_LOOKUP[AWAITING_RELEASE_READY] = EXPIRED
    EXPIRY_LOOKUP[TO_BE_DISPENSED] = EXPIRED
    EXPIRY_LOOKUP[WITH_DISPENSER] = EXPIRED
    EXPIRY_LOOKUP[WITH_DISPENSER_ACTIVE] = DISPENSED
    EXPIRY_LOOKUP[REPEAT_DISPENSE_FUTURE_INSTANCE] = EXPIRED
    EXPIRY_LOOKUP[FUTURE_DATED_PRESCRIPTION] = EXPIRED
    EXPIRY_LOOKUP[PENDING_CANCELLATION] = EXPIRED


class LineItemStatus(object):
    """
    Prescription line item states and related information
    """

    FULLY_DISPENSED = "0001"
    NOT_DISPENSED = "0002"
    PARTIAL_DISPENSED = "0003"
    NOT_DISPENSED_OWING = "0004"
    CANCELLED = "0005"
    EXPIRED = "0006"
    TO_BE_DISPENSED = "0007"
    WITH_DISPENSER = "0008"

    ITEM_CANCELLABLE_STATES = [TO_BE_DISPENSED]
    ITEM_WITH_DISPENSER_STATES = [WITH_DISPENSER, PARTIAL_DISPENSED]

    ACTIVE_STATES = [TO_BE_DISPENSED, WITH_DISPENSER, PARTIAL_DISPENSED, NOT_DISPENSED_OWING]

    INCLUDE_PERFORMER_STATES = [
        WITH_DISPENSER,
        PARTIAL_DISPENSED,
        FULLY_DISPENSED,
        NOT_DISPENSED,
        NOT_DISPENSED_OWING,
    ]

    ITEM_DISPLAY_LOOKUP = {}
    ITEM_DISPLAY_LOOKUP[FULLY_DISPENSED] = "Item fully dispensed"
    ITEM_DISPLAY_LOOKUP[NOT_DISPENSED] = "Item not dispensed"
    ITEM_DISPLAY_LOOKUP[PARTIAL_DISPENSED] = "Item dispensed - partial"
    ITEM_DISPLAY_LOOKUP[NOT_DISPENSED_OWING] = "Item not dispensed owing"
    ITEM_DISPLAY_LOOKUP[EXPIRED] = "Expired"
    ITEM_DISPLAY_LOOKUP[CANCELLED] = "Item Cancelled"
    ITEM_DISPLAY_LOOKUP[TO_BE_DISPENSED] = "To Be Dispensed"
    ITEM_DISPLAY_LOOKUP[WITH_DISPENSER] = "Item with dispenser"

    VALID_STATES = {}
    VALID_STATES[PrescriptionStatus.AWAITING_RELEASE_READY] = [CANCELLED, EXPIRED, TO_BE_DISPENSED]
    VALID_STATES[PrescriptionStatus.TO_BE_DISPENSED] = [CANCELLED, EXPIRED, TO_BE_DISPENSED]
    VALID_STATES[PrescriptionStatus.WITH_DISPENSER] = [CANCELLED, EXPIRED, WITH_DISPENSER]
    VALID_STATES[PrescriptionStatus.WITH_DISPENSER_ACTIVE] = [
        FULLY_DISPENSED,
        NOT_DISPENSED,
        PARTIAL_DISPENSED,
        NOT_DISPENSED_OWING,
        CANCELLED,
        EXPIRED,
        WITH_DISPENSER,
    ]
    VALID_STATES[PrescriptionStatus.EXPIRED] = [CANCELLED, EXPIRED]
    VALID_STATES[PrescriptionStatus.CANCELLED] = [CANCELLED, EXPIRED]
    VALID_STATES[PrescriptionStatus.DISPENSED] = [
        FULLY_DISPENSED,
        NOT_DISPENSED,
        CANCELLED,
        EXPIRED,
    ]
    VALID_STATES[PrescriptionStatus.NOT_DISPENSED] = [NOT_DISPENSED, CANCELLED, EXPIRED]
    VALID_STATES[PrescriptionStatus.CLAIMED] = [FULLY_DISPENSED, NOT_DISPENSED, CANCELLED, EXPIRED]
    VALID_STATES[PrescriptionStatus.NO_CLAIMED] = [
        FULLY_DISPENSED,
        NOT_DISPENSED,
        CANCELLED,
        EXPIRED,
    ]
    VALID_STATES[PrescriptionStatus.REPEAT_DISPENSE_FUTURE_INSTANCE] = [
        CANCELLED,
        EXPIRED,
        TO_BE_DISPENSED,
    ]
    VALID_STATES[PrescriptionStatus.FUTURE_DATED_PRESCRIPTION] = [
        CANCELLED,
        EXPIRED,
        TO_BE_DISPENSED,
    ]

    EXPIRY_IMMUTABLE_STATES = [FULLY_DISPENSED, NOT_DISPENSED, EXPIRED, CANCELLED]

    EXPIRY_LOOKUP = {}
    EXPIRY_LOOKUP[TO_BE_DISPENSED] = "0006"
    EXPIRY_LOOKUP[PARTIAL_DISPENSED] = "0001"
    EXPIRY_LOOKUP[NOT_DISPENSED_OWING] = "0002"
    EXPIRY_LOOKUP[WITH_DISPENSER] = "0006"
