create or replace view sos.v_image as
  select
    "image".image_uuid,
    "image".image_item_uuid,
    "image".image_featured,
    "image".image_mime_type,
    "image".image_date_uploaded,
    "user".user_email as uploader_email
  from sos."image"
    left join sos."user"  on image.image_uploader_uuid = "user".user_uuid
  order by image_date_uploaded asc;

create or replace view sos.v_item as
  select
    "item".*,
    v_image.*,
    coalesce(num_added - num_removed, 0) as item_number_in_stock
  from sos."item"
    left join sos.v_image on item.item_uuid = v_image.image_item_uuid
    left join
      (
        select
          stockchange_item_uuid,
          coalesce(sum(case when stockchange_direction = 'added' then stockchange_change end)::int4, 0) as num_added,
          coalesce(sum(case when stockchange_direction = 'subtracted' then stockchange_change end)::int4, 0) as num_removed
        from sos."item_stockchange"
          group by stockchange_item_uuid
      ) stock_counts
    on stock_counts.stockchange_item_uuid = item.item_uuid;

create or replace view sos.v_cart as
  select * from sos.cart
    left join sos.cart_item on cart_item.cart_item_cart_uuid = cart.cart_uuid
    left join sos.v_item on cart_item.cart_item_item_uuid = v_item.item_uuid;

create or replace view sos.v_session as
  select
    "session".*,
    "session_user".user_email as session_user_email,
    "session_user".user_email_confirmed as session_user_email_confirmed,
    "session_user".user_password_hash as session_user_password_hash,
    "session_user".user_time_registered as session_user_time_registered,
    "session_user".user_time_email_confirmed as session_user_time_email_confirmed,
    "session_user".user_time_password_changed as session_user_time_password_changed,
    "session_user".user_is_admin as session_user_is_admin,
    v_cart.*
  from sos."session"
    left join sos."user" "session_user" on "session".session_user_uuid = "session_user".user_uuid
    left join sos.v_cart on v_cart.cart_uuid = "session".session_cart;


create or replace view sos.v_category as
  select
    "category".*,
    "child_category".category_uuid as child_category_uuid,
    "child_category".category_name as child_category_name,
    "child_category".category_urlslug as child_category_urlslug,
    "child_category".category_description as child_category_description,
	  coalesce("child_item_counts".category_item_count, 0)::int4 as child_category_item_count,
    "parent_category".category_uuid as parent_category_uuid,
    "parent_category".category_name as parent_category_name,
    "parent_category".category_urlslug as parent_category_urlslug,
    v_item.*
  from sos."category"
    left join sos."category_category" "child_category_link" on "category".category_uuid = "child_category_link".category_category_parent_uuid
    left join sos."category_category" "parent_category_link" on "category".category_uuid = "parent_category_link".category_category_child_uuid
    left join sos."category" "child_category" on "child_category_link".category_category_child_uuid = "child_category".category_uuid
    left join (
      select
        category_item_category_uuid as category_uuid,
        count(category_item_item_uuid) as category_item_count
      from sos."category_item"
      	group by category_uuid
    ) child_item_counts on "child_category".category_uuid = "child_item_counts".category_uuid
    left join sos."category" "parent_category" on "parent_category_link".category_category_parent_uuid = "parent_category".category_uuid
    left join sos."category_item" on "category".category_uuid = "category_item".category_item_category_uuid
    left join sos.v_item on "category_item".category_item_item_uuid = item_uuid;

create or replace view sos.v_cart_price as
  select cart_uuid,
      sum(carts.cart_item_price) as cart_price
    from (
      select cart_uuid, cart_item_uuid,
        sum(item_price_cents * cart_item_count) / count(cart_item_uuid) as cart_item_price
      from sos.v_cart
        group by cart_uuid, cart_item_uuid
    ) carts
    group by cart_uuid;

create or replace view sos.v_payment as
  select
    payment.*,
    payment_stripe.stripe_payment_intent_id,
    payment_stripe.stripe_receipt_email
  from sos."payment"
    left join sos."payment_ks_reward" on payment_ks_reward.payment_uuid = payment.payment_uuid and payment_ks_reward.payment_type = payment.payment_type
    left join sos."payment_stripe"    on payment_stripe.payment_uuid    = payment.payment_uuid and payment_stripe.payment_type    = payment.payment_type;

create or replace view sos.v_transaction_paid as
  select
    transaction_uuid,
    coalesce(sum(payment_value_cents), 0) as transaction_amount_paid_cents
  from
    sos."transaction"
    left join sos.v_payment on transaction_uuid = payment_transaction_uuid
    group by transaction_uuid;

create or replace view sos.v_delivery as
  select
    "delivery".*,
    coalesce("delivery_hand_shipped".delivery_tracking_number, "delivery_easypost".delivery_tracking_number) as delivery_tracking_number,
    coalesce("delivery_hand_shipped".delivery_date_shipped, "delivery_easypost".delivery_date_shipped) as delivery_date_shipped,
    coalesce("delivery_hand_shipped".delivery_price_cents, "delivery_easypost".delivery_price_cents) as delivery_price_cents,
    delivery_easypost_id,
    delivery_description,
    delivery_date_delivered
  from sos."delivery"
    left join sos."delivery_hand_shipped" on "delivery".delivery_uuid = "delivery_hand_shipped".delivery_uuid
    left join sos."delivery_hand_delivered" on "delivery".delivery_uuid = "delivery_hand_delivered".delivery_uuid
    left join sos."delivery_easypost" on "delivery".delivery_uuid = "delivery_easypost".delivery_uuid;

create or replace view sos.v_order as
  select
    "order".*,
    "transaction".*,
    (
      transaction_item_total_price
        - transaction_coupon_effective_discount
        + case when (coupon_free_shipping != true) then transaction_shipping_price else 0 end
        + coalesce(transaction_tax_price, 0)
    ) as transaction_computed_price,
    "coupon".*,
    "address".*,
    v_transaction_paid.transaction_amount_paid_cents,
    v_payment.*,
    v_cart.*,
    v_delivery.*
  from sos."order"
    left join sos."transaction" on transaction_order_uuid = order_uuid
    left join sos."coupon" on transaction_coupon_uuid = coupon_uuid
    left join sos."address" on order_address_uuid = address_uuid
    left join sos.v_transaction_paid on "transaction".transaction_uuid = v_transaction_paid.transaction_uuid
    left join sos.v_payment on "transaction".transaction_uuid = payment_transaction_uuid
    left join sos.v_delivery on "order".order_delivery_uuid = delivery_uuid
    left join sos.v_cart on cart_uuid = transaction_cart_uuid;

create or replace view sos.v_config as
  select * from sos."config"
    left join sos."user" on config_updated_by = user_uuid
    left join sos."address" on config_shipping_from = address_uuid
    where config_date_updated = (select max(config_date_updated) from sos."config");

create or replace view sos.v_stockchange as
  select
    item_stockchange.*,
    item_stockchange_shipment.stockchange_shipment_uuid,
    item_stockchange_purchase.stockchange_transaction_uuid,
    item_stockchange_admin.stockchange_withdrawal_uuid
  from sos."item_stockchange"
    left join sos."item_stockchange_shipment" on item_stockchange.stockchange_uuid = item_stockchange_shipment.stockchange_uuid
    left join sos."item_stockchange_purchase" on item_stockchange.stockchange_uuid = item_stockchange_purchase.stockchange_uuid
    left join sos."item_stockchange_admin"    on item_stockchange.stockchange_uuid = item_stockchange_admin.stockchange_uuid;

create or replace view sos.v_shipment as
  select * from sos."shipment"
    left join sos.v_stockchange on v_stockchange.stockchange_shipment_uuid = shipment_uuid
    left join sos.v_item on v_stockchange.stockchange_item_uuid = v_item.item_uuid;

create or replace view sos.v_user as
  select
    "user".*,
    user_num_orders,
    user_last_active
  from sos.user
    left join (
      select
        order_user_uuid,
        count(distinct order_uuid)::int4 user_num_orders
      from sos."v_order"
      where transaction_payment_state = 'completed'
    group by order_user_uuid
    ) "order" on "user".user_uuid = "order".order_user_uuid
    left join (
      select
        session_user_uuid,
        max(session_time_last_active) user_last_active
      from sos."session"
        group by session_user_uuid
    ) "last_session" on "user".user_uuid = "last_session".session_user_uuid;
