{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoFieldSelectors #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

module Tax.Canada.Province.BC.BC428.Types where

import Data.Fixed (Centi)
import Language.Haskell.TH qualified as TH
import Rank2.TH qualified
import Transformation.Shallow.TH qualified

import Tax.Canada.Shared (BaseCredit, MedicalExpenses, SubCalculation, TaxIncomeBracket)

data BC428 line = BC428 {
   forall (line :: * -> *). BC428 line -> Page1 line
page1 :: Page1 line,
   forall (line :: * -> *). BC428 line -> Page2 line
page2 :: Page2 line,
   forall (line :: * -> *). BC428 line -> Page3 line
page3 :: Page3 line}

data Page1 line = Page1 {
   forall (line :: * -> *). Page1 line -> Page1PartA line
partA :: Page1PartA line,
   forall (line :: * -> *). Page1 line -> Page1PartB line
partB :: Page1PartB line}

data Page1PartA line = Page1PartA {
   forall (line :: * -> *). Page1PartA line -> line Centi
income :: line Centi,
   forall (line :: * -> *). Page1PartA line -> TaxIncomeBracket line
column1 :: TaxIncomeBracket line,
   forall (line :: * -> *). Page1PartA line -> TaxIncomeBracket line
column2 :: TaxIncomeBracket line,
   forall (line :: * -> *). Page1PartA line -> TaxIncomeBracket line
column3 :: TaxIncomeBracket line,
   forall (line :: * -> *). Page1PartA line -> TaxIncomeBracket line
column4 :: TaxIncomeBracket line,
   forall (line :: * -> *). Page1PartA line -> TaxIncomeBracket line
column5 :: TaxIncomeBracket line,
   forall (line :: * -> *). Page1PartA line -> TaxIncomeBracket line
column6 :: TaxIncomeBracket line,
   forall (line :: * -> *). Page1PartA line -> TaxIncomeBracket line
column7 :: TaxIncomeBracket line}

data Page1PartB line = Page1PartB {
   forall (line :: * -> *). Page1PartB line -> line Centi
line16_basic :: line Centi,
   forall (line :: * -> *). Page1PartB line -> line Centi
line17_age :: line Centi,
   forall (line :: * -> *). Page1PartB line -> BaseCredit line
spouseAmount :: BaseCredit line,
   forall (line :: * -> *). Page1PartB line -> BaseCredit line
dependantAmount :: BaseCredit line,
   forall (line :: * -> *). Page1PartB line -> line Centi
line24_caregiver :: line Centi,
   forall (line :: * -> *). Page1PartB line -> line Centi
line25 :: line Centi}

data Page2 line = Page2 {
  forall (line :: * -> *). Page2 line -> Page2PartB line
partB :: Page2PartB line}

data Page2PartB line = Page2PartB {
   forall (line :: * -> *). Page2PartB line -> line Centi
line26 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line27_cppQpp :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line28_cppQpp :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line29_employmentInsurance :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line30_employmentInsurance :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line31_firefighters :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line32_rescue :: line Centi,
   forall (line :: * -> *). Page2PartB line -> SubCalculation line
line33_sum :: SubCalculation line,
   forall (line :: * -> *). Page2PartB line -> line Centi
line34_adoption :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line35 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line36_pension :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line37 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line38_disability :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line39 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line40 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line41_interest :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line42_education :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line43_transferredChild :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line44_transferredSpouse :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line45 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> MedicalExpenses line
medicalExpenses :: MedicalExpenses line,
   forall (line :: * -> *). Page2PartB line -> line Centi
line52 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> SubCalculation line
line53_sum :: SubCalculation line,
   forall (line :: * -> *). Page2PartB line -> line Centi
line54 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Rational
line55_rate :: line Rational,
   forall (line :: * -> *). Page2PartB line -> line Centi
line56_fraction :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line57_donations :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line58 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line59_food :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line59_fraction :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line60 :: line Centi}

data PartC line = PartC {
   forall (line :: * -> *). PartC line -> line Centi
line61_tax :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line62_splitIncomeTax :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line63 :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line64_copy :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line65_dividendCredits :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line66_copy :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line66_fraction :: line Centi,
   forall (line :: * -> *). PartC line -> SubCalculation line
line67_sum :: SubCalculation line,
   forall (line :: * -> *). PartC line -> line Centi
line68 :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line69_copy :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line69_fraction :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line70 :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line71_foreignCredit :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line72 :: line Centi}

data Page3 line = Page3 {
   forall (line :: * -> *). Page3 line -> PartC line
partC :: PartC line,
   forall (line :: * -> *). Page3 line -> line Centi
line73_basicReduction :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line74_copy :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line75_base :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line76_difference :: line Centi,
   forall (line :: * -> *). Page3 line -> line Rational
line77_rate :: line Rational,
   forall (line :: * -> *). Page3 line -> SubCalculation line
line78_fraction :: SubCalculation line,
   forall (line :: * -> *). Page3 line -> SubCalculation line
line79_difference :: SubCalculation line,
   forall (line :: * -> *). Page3 line -> line Centi
line80_difference :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line81_logging :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line82_difference :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line83_political :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line84_political :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line85_difference :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line86_esop20 :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line87_evcc30 :: line Centi,
   forall (line :: * -> *). Page3 line -> SubCalculation line
line88_sum :: SubCalculation line,
   forall (line :: * -> *). Page3 line -> line Centi
line89_difference :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line90_mining :: line Centi,
   forall (line :: * -> *). Page3 line -> line Centi
line91_tax :: line Centi}

$(foldMap
   (\t-> concat <$> sequenceA [
       [d|
           deriving instance (Show (line Centi), Show (line Rational), Show (line Word))
                          => Show ($(TH.conT t) line)
           deriving instance (Eq (line Centi), Eq (line Rational), Eq (line Word))
                          => Eq ($(TH.conT t) line)
       |],
       Rank2.TH.deriveAll t,
       Transformation.Shallow.TH.deriveAll t])
   [''BC428, ''Page1, ''Page2, ''Page3,
    ''Page1PartA, ''Page1PartB, ''Page2PartB, ''PartC])