{-# LANGUAGE DisambiguateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NoFieldSelectors #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

module Tax.Canada.Province.BC (BC428, bc428Fields, bc479Fields, fixBC428, fixBC479, fixReturns, returnFields, t1Fields) where

import Data.CAProvinceCodes (Code(BC))
import Rank2 qualified
import Rank2.TH qualified
import Transformation.Shallow.TH qualified

import Tax.Canada.Federal qualified as Federal
import Tax.Canada.Federal (Forms(t1), fixFederalForms)
import Tax.Canada.T1.Types (T1 (T1, page7, page8), Page7(Page7, step6_RefundOrBalanceOwing), Page8(Page8))
import Tax.Canada.T1.Types qualified as T1
import Tax.Canada.T1.Types qualified as Page8 (Page8(..))
import Tax.Canada.T1.FieldNames.BC (t1Fields)

import Tax.Canada.Province.BC.BC428.Types qualified as BC
import Tax.Canada.Province.BC.BC428.Types qualified as BC.Page1 (Page1(..))
import Tax.Canada.Province.BC.BC428.Types qualified as BC.Page2 (Page2(..))
import Tax.Canada.Province.BC.BC428.Types (BC428 (BC428))
import Tax.Canada.Province.BC.BC428.Fix (fixBC428)
import Tax.Canada.Province.BC.BC428.FieldNames (bc428Fields)
import Tax.Canada.Province.BC.BC479.Types qualified as BCC
import Tax.Canada.Province.BC.BC479.Types (BC479 (BC479))
import Tax.Canada.Province.BC.BC479.Fix (fixBC479)
import Tax.Canada.Province.BC.BC479.FieldNames (bc479Fields)

import Tax.Canada.Shared(MedicalExpenses(..), BaseCredit(..))
import Tax.FDF (FieldConst, within)
import Tax.Util (fixEq, totalOf)

data Returns line = Returns {
  forall (line :: * -> *). Returns line -> Forms line
federal :: Federal.Forms line,
  forall (line :: * -> *). Returns line -> BC428 line
bc428 :: BC428 line,
  forall (line :: * -> *). Returns line -> BC479 line
bc479 :: BC479 line}

deriving instance (Show (Federal.Forms line), Show (BC428 line), Show (BC479 line)) => Show (Returns line)
deriving instance (Eq (Federal.Forms line), Eq (BC428 line), Eq (BC479 line)) => Eq (Returns line)
Rank2.TH.deriveAll ''Returns
Transformation.Shallow.TH.deriveAll ''Returns

fixReturns :: Returns Maybe -> Returns Maybe
fixReturns :: Returns Maybe -> Returns Maybe
fixReturns =
  (Returns Maybe -> Returns Maybe) -> Returns Maybe -> Returns Maybe
forall a. Eq a => (a -> a) -> a -> a
fixEq ((Returns Maybe -> Returns Maybe)
 -> Returns Maybe -> Returns Maybe)
-> (Returns Maybe -> Returns Maybe)
-> Returns Maybe
-> Returns Maybe
forall a b. (a -> b) -> a -> b
$ \Returns{$sel:federal:Returns :: forall (line :: * -> *). Returns line -> Forms line
federal = ff :: Forms Maybe
ff@Federal.Forms{$sel:t1:Forms :: forall (line :: * -> *). Forms line -> T1 line
t1 = t1 :: T1 Maybe
t1@T1{$sel:page7:T1 :: forall (line :: * -> *). T1 line -> Page7 line
page7 = page7 :: Page7 Maybe
page7@Page7{Page7Step6 Maybe
$sel:step6_RefundOrBalanceOwing:Page7 :: forall (line :: * -> *). Page7 line -> Page7Step6 line
step6_RefundOrBalanceOwing :: Page7Step6 Maybe
step6_RefundOrBalanceOwing},
                                                         $sel:page8:T1 :: forall (line :: * -> *). T1 line -> Page8 line
page8 = page8 :: Page8 Maybe
page8@Page8{$sel:step6_RefundOrBalanceOwing:Page8 :: forall (line :: * -> *). Page8 line -> Page8Step6 line
step6_RefundOrBalanceOwing = Page8Step6 Maybe
page8step6}}},
                   $sel:bc428:Returns :: forall (line :: * -> *). Returns line -> BC428 line
bc428 = bc428 :: BC428 Maybe
bc428@BC428{$sel:page1:BC428 :: forall (line :: * -> *). BC428 line -> Page1 line
page1 = page1 :: Page1 Maybe
page1@BC.Page1{Page1PartA Maybe
partA :: Page1PartA Maybe
$sel:partA:Page1 :: forall (line :: * -> *). Page1 line -> Page1PartA line
partA, $sel:partB:Page1 :: forall (line :: * -> *). Page1 line -> Page1PartB line
partB = partB1 :: Page1PartB Maybe
partB1@BC.Page1PartB{BaseCredit Maybe
spouseAmount :: BaseCredit Maybe
$sel:spouseAmount:Page1PartB :: forall (line :: * -> *). Page1PartB line -> BaseCredit line
spouseAmount}},
                                       $sel:page2:BC428 :: forall (line :: * -> *). BC428 line -> Page2 line
page2 = page2 :: Page2 Maybe
page2@BC.Page2{$sel:partB:Page2 :: forall (line :: * -> *). Page2 line -> Page2PartB line
BC.partB = partB2 :: Page2PartB Maybe
partB2@BC.Page2PartB{MedicalExpenses Maybe
medicalExpenses :: MedicalExpenses Maybe
$sel:medicalExpenses:Page2PartB :: forall (line :: * -> *). Page2PartB line -> MedicalExpenses line
BC.medicalExpenses}},
                                       $sel:page3:BC428 :: forall (line :: * -> *). BC428 line -> Page3 line
page3 = page3 :: Page3 Maybe
page3@BC.Page3{PartC Maybe
partC :: PartC Maybe
$sel:partC:Page3 :: forall (line :: * -> *). Page3 line -> PartC line
BC.partC}},
                   BC479 Maybe
$sel:bc479:Returns :: forall (line :: * -> *). Returns line -> BC479 line
bc479 :: BC479 Maybe
bc479}
          -> Returns{$sel:federal:Returns :: Forms Maybe
federal = Forms Maybe -> Forms Maybe
fixFederalForms
                               Forms Maybe
ff{t1 = t1{page7 =
                                          page7{step6_RefundOrBalanceOwing =
                                                step6_RefundOrBalanceOwing{T1.line_42800_ProvTerrTax =
                                                                           bc428.page3.line91_tax}},
                                          page8 =
                                          page8{Page8.step6_RefundOrBalanceOwing =
                                                page8step6{T1.line_47900_ProvTerrCredits =
                                                           bc479.page3.line42_credits}}}},
                     $sel:bc428:Returns :: BC428 Maybe
bc428 = BC428 Maybe -> BC428 Maybe
fixBC428
                             BC428 Maybe
bc428{BC.page1 =
                                   page1{BC.Page1.partA =
                                         partA{BC.income = t1.page5.step4_TaxableIncome.line_26000_TaxableIncome},
                                         BC.Page1.partB =
                                         partB1{BC.spouseAmount = spouseAmount{reduction = t1.page1.spouse.line23600}}
                                        },
                                   BC.page2 =
                                   page2{BC.Page2.partB = partB2{BC.line27_cppQpp = t1.page6.line30800,
                                                                 BC.line28_cppQpp = t1.page6.line31000,
                                                                 BC.line29_employmentInsurance = t1.page6.line31200,
                                                                 BC.line30_employmentInsurance = t1.page6.line31217,
                                                                 BC.line41_interest = t1.page6.line31900,
                                                                 BC.medicalExpenses =
                                                                 medicalExpenses{
                                                                    expenses = t1.page6.medical_expenses.familyExpenses,
                                                                    netIncome = t1.page4.line_23600_NetIncome}}},
                                    BC.page3 =
                                    page3{BC.partC = partC{BC.line66_copy = t1.page7.partC_NetFederalTax.line40427},
                                          BC.line74_copy = t1.page4.line_23600_NetIncome}},
                     $sel:bc479:Returns :: BC479 Maybe
bc479 = BC479 Maybe -> BC479 Maybe
fixBC479
                             BC479 Maybe
bc479{BCC.page1 =
                                   bc479.page1{BCC.line1_netIncome_self = t1.page4.line_23600_NetIncome,
                                               BCC.line1_netIncome_spouse = t1.page1.spouse.line23600,
                                               BCC.line4_uccb_rdsp_income_self = totalOf [t1.page3.line_11700_UCCB,
                                                                                          t1.page3.line_12500_RDSP],
                                               BCC.line7_threshold = if t1.page1.identification.maritalStatus
                                                                        `elem` [Just T1.Married,
                                                                                Just T1.LivingCommonLaw]
                                                                     then Just 18_000
                                                                     else 15_000 <$ t1.page1.identification.maritalStatus}}}

returnFields :: Returns FieldConst
returnFields :: Returns FieldConst
returnFields = Returns{
  $sel:federal:Returns :: Forms FieldConst
federal = Code -> Forms FieldConst
Federal.formFieldsForProvince Code
BC,
  $sel:bc428:Returns :: BC428 FieldConst
bc428 = Text -> FieldConst a -> FieldConst a
forall x. Text -> FieldConst x -> FieldConst x
within Text
"428" (forall {a}. FieldConst a -> FieldConst a)
-> BC428 FieldConst -> BC428 FieldConst
forall {k} (g :: (k -> *) -> *) (p :: k -> *) (q :: k -> *).
Functor g =>
(forall (a :: k). p a -> q a) -> g p -> g q
forall (p :: * -> *) (q :: * -> *).
(forall a. p a -> q a) -> BC428 p -> BC428 q
Rank2.<$> BC428 FieldConst
bc428Fields,
  $sel:bc479:Returns :: BC479 FieldConst
bc479 = Text -> FieldConst a -> FieldConst a
forall x. Text -> FieldConst x -> FieldConst x
within Text
"479" (forall {a}. FieldConst a -> FieldConst a)
-> BC479 FieldConst -> BC479 FieldConst
forall {k} (g :: (k -> *) -> *) (p :: k -> *) (q :: k -> *).
Functor g =>
(forall (a :: k). p a -> q a) -> g p -> g q
forall (p :: * -> *) (q :: * -> *).
(forall a. p a -> q a) -> BC479 p -> BC479 q
Rank2.<$> BC479 FieldConst
bc479Fields}