{-# 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.AB.AB428.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 AB428 line = AB428 {
   forall (line :: * -> *). AB428 line -> Page1 line
page1 :: Page1 line,
   forall (line :: * -> *). AB428 line -> Page2 line
page2 :: Page2 line,
   forall (line :: * -> *). AB428 line -> Page3 line
page3 :: Page3 line}

data Page1 line = Page1 {
   forall (line :: * -> *). Page1 line -> line Centi
income :: line Centi,
   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 -> 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}

data Page1PartB line = Page1PartB {
   forall (line :: * -> *). Page1PartB line -> line Centi
line9_basic :: line Centi,
   forall (line :: * -> *). Page1PartB line -> line Centi
line10_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
line17_infirm :: line Centi,
   forall (line :: * -> *). Page1PartB line -> line Centi
line18 :: line Centi,
   forall (line :: * -> *). Page1PartB line -> line Centi
line19_cppQpp :: line Centi,
   forall (line :: * -> *). Page1PartB line -> line Centi
line20_cppQpp :: line Centi,
   forall (line :: * -> *). Page1PartB line -> line Centi
line21_employmentInsurance :: line Centi,
   forall (line :: * -> *). Page1PartB line -> line Centi
line22_employmentInsurance :: line Centi,
   forall (line :: * -> *). Page1PartB line -> line Centi
line23_adoption :: line Centi,
   forall (line :: * -> *). Page1PartB line -> SubCalculation line
line24_sum :: SubCalculation line,
   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_pension :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line28_caregiver :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line29 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line30_disability :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line31 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line32 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line33_interest :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line34_education :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line35_transferredSpouse :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Centi
line36 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> MedicalExpenses line
medicalExpenses :: MedicalExpenses line,
   forall (line :: * -> *). Page2PartB line -> line Centi
line43 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> SubCalculation line
line44_sum :: SubCalculation line,
   forall (line :: * -> *). Page2PartB line -> line Centi
line45 :: line Centi,
   forall (line :: * -> *). Page2PartB line -> line Rational
line46_rate :: line Rational,
   forall (line :: * -> *). Page2PartB line -> line Centi
line47_fraction :: line Centi,
   forall (line :: * -> *). Page2PartB line -> Donations line
donations :: Donations line,
   forall (line :: * -> *). Page2PartB line -> SubCalculation line
line50_sum :: SubCalculation line,
   forall (line :: * -> *). Page2PartB line -> line Centi
line51 :: line Centi}

data Donations line = Donations {
   forall (line :: * -> *). Donations line -> line Centi
line48_base :: line Centi,
   forall (line :: * -> *). Donations line -> line Centi
line48_fraction :: line Centi,
   forall (line :: * -> *). Donations line -> line Centi
line49_base :: line Centi,
   forall (line :: * -> *). Donations line -> line Centi
line49_fraction :: line Centi}

data Page3 line = Page3 {
   forall (line :: * -> *). Page3 line -> PartC line
partC :: PartC line,
   forall (line :: * -> *). Page3 line -> PartD line
partD :: PartD line}

data PartC line = PartC {
   forall (line :: * -> *). PartC line -> line Centi
line52_tax :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line53_splitIncomeTax :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line54 :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line55_copy :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line56_dividendCredits :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line57_copy :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line57_fraction :: line Centi,
   forall (line :: * -> *). PartC line -> SubCalculation line
line58_sum :: SubCalculation line,
   forall (line :: * -> *). PartC line -> line Centi
line59_difference :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line60_fromT691 :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line60_fraction :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line61 :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line62_foreignCredit :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line63_difference :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line64_political :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line65_political :: line Centi,
   forall (line :: * -> *). PartC line -> line Centi
line66_tax :: line Centi}

data PartD line = PartD {
   forall (line :: * -> *). PartD line -> line Centi
line67_investorCredit :: line Centi,
   forall (line :: * -> *). PartD line -> line Centi
line68_stockCredit :: line Centi,
   forall (line :: * -> *). PartD line -> line Centi
line69_credits :: 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])
   [''AB428, ''Page1, ''Page2, ''Page3,
    ''Page1PartA, ''Page1PartB, ''Page2PartB, ''PartC, ''PartD, ''Donations])