{-# OPTIONS --lossy-unification #-}
module Cubical.Categories.Displayed.Limits.BinProduct.Fiberwise where

open import Cubical.Foundations.Prelude
open import Cubical.Foundations.More
open import Cubical.Foundations.Isomorphism
open import Cubical.Foundations.Equiv.Dependent
open import Cubical.Foundations.Function

open import Cubical.Categories.Category.Base
open import Cubical.Categories.Instances.Fiber
open import Cubical.Categories.Limits.BinProduct.More
open import Cubical.Categories.Presheaf

open import Cubical.Categories.Displayed.Base
open import Cubical.Categories.Displayed.Presheaf

open import Cubical.Categories.Displayed.Limits.BinProduct.Base

private
  variable
    ℓC ℓC' ℓCᴰ ℓCᴰ' ℓD ℓD' ℓDᴰ ℓDᴰ' : Level

open Category
open UniversalElement
open UniversalElementᴰ
open UniversalElementⱽ
open isIsoOver

module _ {C : Category ℓC ℓC'}(Cᴰ : Categoryᴰ C ℓCᴰ ℓCᴰ') where
  private
    module C = Category C
    module Cᴰ = Fibers Cᴰ

  module _ {a} {aᴰ₁ aᴰ₂} (bpⱽ : BinProductⱽ Cᴰ (aᴰ₁ , aᴰ₂)) where
    private
      module a₁×ⱽa₂ = BinProductⱽNotation _ bpⱽ

    opaque
      unfolding hSetReasoning.reind
      BinProductⱽ→BinProductFiber : BinProduct Cᴰ.v[ a ] (aᴰ₁ , aᴰ₂)
      BinProductⱽ→BinProductFiber .vertex = a₁×ⱽa₂.×ueⱽ.vertexⱽ
      BinProductⱽ→BinProductFiber .element = a₁×ⱽa₂.×ueⱽ.elementⱽ
      BinProductⱽ→BinProductFiber .universal Γᴰ =
        isIsoToIsEquiv
            ( a₁×ⱽa₂.×ueⱽ.introⱽ
            ,  f  a₁×ⱽa₂.×ueⱽ.Pshⱽ.rectify $ a₁×ⱽa₂.×ueⱽ.Pshⱽ.≡out $
                (sym $ a₁×ⱽa₂.×ueⱽ.Pshⱽ.reind-filler _)
                 a₁×ⱽa₂.×ueⱽ.βᴰ
                )
            , λ f  Cᴰ.rectify $ Cᴰ.≡out $
                a₁×ⱽa₂.×ueⱽ.introᴰ≡ (sym $ a₁×ⱽa₂.×ueⱽ.Pshⱽ.reind-filler _)
                )

  -- TODO: prove that cartesian lifts preserves these binary products
  -- cartesianLift-preserves-BinProductFiber :
  --   ∀ {a b aᴰ₁ aᴰ₂}
  --   → (isFib : isFibration Cᴰ)
  --   → (bpⱽ : BinProductⱽ Cᴰ (aᴰ₁ , aᴰ₂))
  --   → (f : C [ b , a ])
  --   → preservesBinProduct (CatFib.CartesianLiftF-fiber Cᴰ isFib f)
  --     (BinProductⱽ→BinProductFiber bpⱽ)
  -- cartesianLift-preserves-BinProductFiber {b = b}{aᴰ₁}{aᴰ₂} isFib bpⱽ f bᴰ = isIsoToIsEquiv
  --   ( (λ (fⱽ₁ , fⱽ₂) → f*×.intro (bpⱽ.×ueⱽ.introᴰ ((fⱽ₁ Cᴰ.⋆ᴰ f*aᴰ₁.π) , (fⱽ₂ Cᴰ.⋆ᴰ f*aᴰ₂.π))))
  --   , (λ (fⱽ₁ , fⱽ₂) → ΣPathP
  --       -- This part of the proof can probably be simplified
  --       ((Cᴰ.rectify $ Cᴰ.≡out $
  --         (sym $ Cᴰ.reind-filler _)
  --         ∙ f*aᴰ₁.introL-natural
  --         ∙ f*aᴰ₁.introCL≡' (C.⋆IdL _)
  --           ((sym $ Cᴰ.reind-filler _)
  --           ∙ Cᴰ.⟨ refl ⟩⋆⟨ Cᴰ.⋆IdL _ ∙ (sym $ Cᴰ.reind-filler _) ⟩
  --           ∙ (sym $ Cᴰ.⋆Assoc _ _ _)
  --           ∙ Cᴰ.⟨ f*×.βCL ⟩⋆⟨ refl ⟩
  --           ∙ Cᴰ.reind-filler _
  --           ∙ bpⱽ.∫×βⱽ₁))
  --       , (Cᴰ.rectify $ Cᴰ.≡out $
  --         (sym $ Cᴰ.reind-filler _)
  --         ∙ f*aᴰ₂.introCL-natural
  --         ∙ f*aᴰ₂.introCL≡' (C.⋆IdL _)
  --           ((sym $ Cᴰ.reind-filler _)
  --           ∙ Cᴰ.⟨ refl ⟩⋆⟨ Cᴰ.⋆IdL _ ∙ (sym $ Cᴰ.reind-filler _) ⟩
  --           ∙ (sym $ Cᴰ.⋆Assoc _ _ _)
  --           ∙ Cᴰ.⟨ f*×.βCL ⟩⋆⟨ refl ⟩
  --           ∙ Cᴰ.reind-filler _
  --           ∙ bpⱽ.∫×βⱽ₂))
  --       ))
  --   , λ fⱽ → Cᴰ.rectify $ Cᴰ.≡out $
  --         f*×.introCL≡ (bpⱽ.,ⱽ≡
  --           (Cᴰ.⟨ sym $ Cᴰ.reind-filler _ ⟩⋆⟨ refl ⟩
  --             ∙ Cᴰ.⋆Assoc _ _ _
  --             ∙ Cᴰ.⟨ refl ⟩⋆⟨ f*aᴰ₁.βCL ∙ Cᴰ.⋆IdL _ ∙ (sym $ Cᴰ.reind-filler _) ⟩
  --             ∙ (sym $ Cᴰ.⋆Assoc _ _ _)
  --             ∙ Cᴰ.reind-filler _)
  --           (Cᴰ.⟨ sym $ Cᴰ.reind-filler _ ⟩⋆⟨ refl ⟩
  --             ∙ Cᴰ.⋆Assoc _ _ _
  --             ∙ Cᴰ.⟨ refl ⟩⋆⟨ f*aᴰ₂.βCL ∙ Cᴰ.⋆IdL _ ∙ (sym $ Cᴰ.reind-filler _) ⟩
  --             ∙ (sym $ Cᴰ.⋆Assoc _ _ _)
  --             ∙ Cᴰ.reind-filler _))
  --     )
  --   where
  --   module f*× = CartesianLift (isFib (vertexⱽ bpⱽ) f)
  --   module f*aᴰ₁ = CartesianLift (isFib aᴰ₁ f)
  --   module f*aᴰ₂ = CartesianLift (isFib aᴰ₂ f)
  --   module bpⱽ = BinProductⱽNotation _ bpⱽ
  --   module f*⟨aᴰ₁×aᴰ₂⟩ = PresheafNotation (BinProductProf Cᴰ.v[ b ] ⟅ f*aᴰ₁.p*Pᴰ , f*aᴰ₂.p*Pᴰ ⟆)

  BinProductsWithⱽ→BinProductsWithFiber :  {a} {aᴰ}
     BinProductsWithⱽ Cᴰ aᴰ
     BinProductsWith Cᴰ.v[ a ] aᴰ
  BinProductsWithⱽ→BinProductsWithFiber -×ⱽaᴰ aᴰ' =
    BinProductⱽ→BinProductFiber (-×ⱽaᴰ aᴰ')