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

module Tax.Canada.Province.ON (Returns(..), ON428, ON479, fixON428, fixON479, fixReturns,
                               returnFields, t1Fields, on428Fields, on479Fields) where

import Data.CAProvinceCodes (Code(ON))
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.Federal.Schedule9 qualified as Schedule9
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.ON (t1Fields)

import Tax.Canada.Province.ON.ON428.Types qualified as ON
import Tax.Canada.Province.ON.ON428.Types qualified as ON.Page1 (Page1(..))
import Tax.Canada.Province.ON.ON428.Types qualified as ON.Page2 (Page2(..))
import Tax.Canada.Province.ON.ON428.Types (ON428 (ON428))
import Tax.Canada.Province.ON.ON428.Fix (fixON428)
import Tax.Canada.Province.ON.ON428.FieldNames (on428Fields)
import Tax.Canada.Province.ON.ON479.Types (ON479 (ON479, page2), Page2(line23_credits))
import Tax.Canada.Province.ON.ON479.Fix (fixON479)
import Tax.Canada.Province.ON.ON479.FieldNames (on479Fields)

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

data Returns line = Returns {
  forall (line :: * -> *). Returns line -> Forms line
federal :: Federal.Forms line,
  forall (line :: * -> *). Returns line -> ON428 line
on428 :: ON428 line,
  forall (line :: * -> *). Returns line -> ON479 line
on479 :: ON479 line}

deriving instance (Show (Federal.Forms line), Show (ON428 line), Show (ON479 line)) => Show (Returns line)
deriving instance (Eq (Federal.Forms line), Eq (ON428 line), Eq (ON479 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}},
                                              Schedule9 Maybe
schedule9 :: Schedule9 Maybe
$sel:schedule9:Forms :: forall (line :: * -> *). Forms line -> Schedule9 line
schedule9},
                   $sel:on428:Returns :: forall (line :: * -> *). Returns line -> ON428 line
on428 = on428 :: ON428 Maybe
on428@ON428{$sel:page1:ON428 :: forall (line :: * -> *). ON428 line -> Page1 line
page1 = page1 :: Page1 Maybe
page1@ON.Page1{$sel:partB:Page1 :: forall (line :: * -> *). Page1 line -> Page1PartB line
partB = partB1 :: Page1PartB Maybe
partB1@ON.Page1PartB{BaseCredit Maybe
spouseAmount :: BaseCredit Maybe
$sel:spouseAmount:Page1PartB :: forall (line :: * -> *). Page1PartB line -> BaseCredit line
spouseAmount}},
                                       $sel:page2:ON428 :: forall (line :: * -> *). ON428 line -> Page2 line
page2 = page2 :: Page2 Maybe
page2@ON.Page2{$sel:partB:Page2 :: forall (line :: * -> *). Page2 line -> Page2PartB line
ON.partB = partB2 :: Page2PartB Maybe
partB2@ON.Page2PartB{MedicalExpenses Maybe
medicalExpenses :: MedicalExpenses Maybe
$sel:medicalExpenses:Page2PartB :: forall (line :: * -> *). Page2PartB line -> MedicalExpenses line
ON.medicalExpenses},
                                                              Page2PartC Maybe
partC :: Page2PartC Maybe
$sel:partC:Page2 :: forall (line :: * -> *). Page2 line -> Page2PartC line
ON.partC}},
                   ON479 Maybe
$sel:on479:Returns :: forall (line :: * -> *). Returns line -> ON479 line
on479 :: ON479 Maybe
on479}
          -> 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=
                                                                                      on428.page4.line90}},
                                                     page8 =
                                                     page8{Page8.step6_RefundOrBalanceOwing =
                                                           page8step6{T1.line_47900_ProvTerrCredits =
                                                                      on479.page2.line23_credits}}}},
                     $sel:on428:Returns :: ON428 Maybe
on428 = ON428 Maybe -> ON428 Maybe
fixON428 ON428 Maybe
on428{
                        ON.page1 =
                            page1{ON.line1 = t1.page5.step4_TaxableIncome.line_26000_TaxableIncome,
                                  ON.Page1.partB = partB1{ON.spouseAmount = spouseAmount{reduction = t1.page1.spouse.line23600},
                                                          ON.line19_cppQpp = t1.page6.line30800,
                                                          ON.line20_cppQpp = t1.page6.line31000,
                                                          ON.line21_employmentInsurance = t1.page6.line31200,
                                                          ON.line22_employmentInsurance = t1.page6.line31217}},
                        ON.page2 =
                            page2{ON.Page2.partB = partB2{ON.line32_interest = t1.page6.line31900,
                                                          ON.medicalExpenses =
                                                             medicalExpenses{
                                                             netIncome = t1.page4.line_23600_NetIncome},
                                                          ON.donations = partB2.donations{
                                                             ON.line47_base = schedule9.line13_min,
                                                             ON.line48_base = schedule9.line14_difference}},
                                  ON.partC = partC{ON.line59_copy = t1.page7.partC_NetFederalTax.line40427}}},
                     ON479 Maybe
$sel:on479:Returns :: ON479 Maybe
on479 :: ON479 Maybe
on479}

returnFields :: Returns FieldConst
returnFields :: Returns FieldConst
returnFields = Returns{
  $sel:federal:Returns :: Forms FieldConst
federal = Code -> Forms FieldConst
Federal.formFieldsForProvince Code
ON,
  $sel:on428:Returns :: ON428 FieldConst
on428 = Text -> FieldConst a -> FieldConst a
forall x. Text -> FieldConst x -> FieldConst x
within Text
"428" (forall {a}. FieldConst a -> FieldConst a)
-> ON428 FieldConst -> ON428 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) -> ON428 p -> ON428 q
Rank2.<$> ON428 FieldConst
on428Fields,
  $sel:on479:Returns :: ON479 FieldConst
on479 = Text -> FieldConst a -> FieldConst a
forall x. Text -> FieldConst x -> FieldConst x
within Text
"479" (forall {a}. FieldConst a -> FieldConst a)
-> ON479 FieldConst -> ON479 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) -> ON479 p -> ON479 q
Rank2.<$> ON479 FieldConst
on479Fields}