content: module IHP.IDE.CodeGen.ApplicationGenerator (buildPlan) where
  
  import IHP.Prelude
  import IHP.IDE.CodeGen.Types
  
  buildPlan :: Text -> IO (Either Text [GeneratorAction])
  buildPlan applicationName =
      if (null applicationName)
          then do
              pure $ Left "Application name cannot be empty"
          else do
              let applicationName' = ucfirst applicationName
              pure $ Right $ generateGenericApplication applicationName'
  
  generateGenericApplication :: Text -> [GeneratorAction]
  generateGenericApplication applicationName =
          let
              typesHs =
                  "module " <> applicationName <> ".Types where\n\n"
                  <> "import IHP.Prelude\n"
                  <> "import IHP.ModelSupport\n"
                  <> "import Generated.Types\n\n"
                  <> "data " <> applicationName <> "Application = " <> applicationName <> "Application deriving (Eq, Show)\n\n"
                  <> "\n"
                  <> "data StaticController = WelcomeAction deriving (Eq, Show, Data)"
                  <> "\n"
  
              routesHs =
                  "module " <> applicationName <> ".Routes where\n"
                  <> "import IHP.RouterPrelude\n"
                  <> "import Generated.Types\n"
                  <> "import " <> applicationName <> ".Types\n\n"
                  <> "-- Generator Marker\n"
                  <> "instance AutoRoute StaticController"
              frontControllerHs =
                  "module " <> applicationName <> ".FrontController where\n\n"
                  <> "import IHP.RouterPrelude\n"
                  <> "import " <> applicationName <> ".Controller.Prelude\n"
                  <> "import " <> applicationName <> ".View.Layout (defaultLayout)\n\n"
                  <> "-- Controller Imports\n"
                  <> "import " <> applicationName <> ".Controller.Static\n\n"
                  <> "instance FrontController " <> applicationName <> "Application where\n"
                  <> "    controllers = \n"
                  <> "        [ startPage WelcomeAction\n"
                  <> "        -- Generator Marker\n"
                  <> "        ]\n\n"
                  <> "instance InitControllerContext " <> applicationName <> "Application where\n"
                  <> "    initContext = do\n"
                  <> "        setLayout defaultLayout\n"
                  <> "        initAutoRefresh\n"
              controllerPreludeHs =
                  "module " <> applicationName <> ".Controller.Prelude\n"
                  <> "( module " <> applicationName <> ".Types\n"
                  <> ", module Application.Helper.Controller\n"
                  <> ", module IHP.ControllerPrelude\n"
                  <> ", module Generated.Types\n"
                  <> ")\n"
                  <> "where\n\n"
                  <> "import " <> applicationName <> ".Types\n"
                  <> "import Application.Helper.Controller\n"
                  <> "import IHP.ControllerPrelude\n"
                  <> "import Generated.Types\n"
                  <> "import " <> applicationName <> ".Routes\n"
  
              viewLayoutHs =
                  "module " <> applicationName <> ".View.Layout (defaultLayout, Html) where\n"
                  <> "\n"
                  <> "import IHP.ViewPrelude\n"
                  <> "import IHP.Environment\n"
                  <> "import Generated.Types\n"
                  <> "import IHP.Controller.RequestContext\n"
                  <> "import " <> applicationName <> ".Types\n"
                  <> "import " <> applicationName <> ".Routes\n"
                  <> "import Application.Helper.View\n"
                  <> "\n"
                  <> "defaultLayout :: Html -> Html\n"
                  <> "defaultLayout inner = [hsx|\n"
                  <> "<!DOCTYPE html>\n"
                  <> "<html lang=\"en\">\n"
                  <> "    <head>\n"
                  <> "        {metaTags}\n"
                  <> "\n"
                  <> "        {stylesheets}\n"
                  <> "        {scripts}\n"
                  <> "\n"
                  <> "        <title>{pageTitleOrDefault \"App\"}</title>\n"
                  <> "    </head>\n"
                  <> "    <body>\n"
                  <> "        <div class=\"container mt-4\">\n"
                  <> "            {renderFlashMessages}\n"
                  <> "            {inner}\n"
                  <> "        </div>\n"
                  <> "    </body>\n"
                  <> "</html>\n"
                  <> "|]\n"
                  <> "\n"
                  <> "-- The 'assetPath' function used below appends a `?v=SOME_VERSION` to the static assets in production\n"
                  <> "-- This is useful to avoid users having old CSS and JS files in their browser cache once a new version is deployed\n"
                  <> "-- See https://ihp.digitallyinduced.com/Guide/assets.html for more details\n"
                  <> "\n"
                  <> "stylesheets :: Html\n"
                  <> "stylesheets = [hsx|\n"
                  <> "        <link rel=\"stylesheet\" href={assetPath \"/vendor/bootstrap-5.2.1/bootstrap.min.css\"}/>\n"
                  <> "        <link rel=\"stylesheet\" href={assetPath \"/vendor/flatpickr.min.css\"}/>\n"
                  <> "        <link rel=\"stylesheet\" href={assetPath \"/app.css\"}/>\n"
                  <> "    |]\n"
                  <> "\n"
                  <> "scripts :: Html\n"
                  <> "scripts = [hsx|\n"
                  <> "        {when isDevelopment devScripts}\n"
                  <> "        <script src={assetPath \"/vendor/jquery-3.6.0.slim.min.js\"}></script>\n"
                  <> "        <script src={assetPath \"/vendor/timeago.js\"}></script>\n"
                  <> "        <script src={assetPath \"/vendor/popper-2.11.6.min.js\"}></script>\n"
                  <> "        <script src={assetPath \"/vendor/bootstrap-5.2.1/bootstrap.min.js\"}></script>\n"
                  <> "        <script src={assetPath \"/vendor/flatpickr.js\"}></script>\n"
                  <> "        <script src={assetPath \"/vendor/morphdom-umd.min.js\"}></script>\n"
                  <> "        <script src={assetPath \"/vendor/turbolinks.js\"}></script>\n"
                  <> "        <script src={assetPath \"/vendor/turbolinksInstantClick.js\"}></script>\n"
                  <> "        <script src={assetPath \"/vendor/turbolinksMorphdom.js\"}></script>\n"
                  <> "        <script src={assetPath \"/helpers.js\"}></script>\n"
                  <> "        <script src={assetPath \"/ihp-auto-refresh.js\"}></script>\n"
                  <> "        <script src={assetPath \"/app.js\"}></script>\n"
                  <> "    |]\n"
                  <> "\n"
                  <> "devScripts :: Html\n"
                  <> "devScripts = [hsx|\n"
                  <> "        <script id=\"livereload-script\" src={assetPath \"/livereload.js\"} data-ws={liveReloadWebsocketUrl}></script>\n"
                  <> "    |]\n"
                  <> "\n"
                  <> "metaTags :: Html\n"
                  <> "metaTags = [hsx|\n"
                  <> "    <meta charset=\"utf-8\"/>\n"
                  <> "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\"/>\n"
                  <> "    <meta property=\"og:title\" content=\"App\"/>\n"
                  <> "    <meta property=\"og:type\" content=\"website\"/>\n"
                  <> "    <meta property=\"og:url\" content=\"TODO\"/>\n"
                  <> "    <meta property=\"og:description\" content=\"TODO\"/>\n"
                  <> "    {autoRefreshMeta}\n"
                  <> "|]\n"
  
              viewPreludeHs =
                  "module " <> applicationName <> ".View.Prelude\n"
                  <> "( module IHP.ViewPrelude\n"
                  <> ", module " <> applicationName <> ".View.Layout\n"
                  <> ", module Generated.Types\n"
                  <> ", module " <> applicationName <> ".Types\n"
                  <> ", module Application.Helper.View\n"
                  <> ") where\n"
                  <> "\n"
                  <> "import IHP.ViewPrelude\n"
                  <> "import " <> applicationName <> ".View.Layout\n"
                  <> "import Generated.Types\n"
                  <> "import " <> applicationName <> ".Types\n"
                  <> "import " <> applicationName <> ".Routes ()\n"
                  <> "import Application.Helper.View\n"
  
              welcomeControllerStaticHs =
                  "module " <> applicationName <> ".Controller.Static where\n"
                  <> "import " <> applicationName  <>".Controller.Prelude\n"
                  <> "import " <> applicationName  <>".View.Static.Welcome\n"
                  <> "\n"
                  <> "instance Controller StaticController where\n"
                  <> "    action WelcomeAction = render WelcomeView\n"
  
              welcomeViewStaticHs =
                "module " <> applicationName <> ".View.Static.Welcome where\n"
               <>"import " <> applicationName <> ".View.Prelude\n"
               <>"\n"
               <>"data WelcomeView = WelcomeView\n"
               <>"\n"
               <>"instance View WelcomeView where\n"
               <>"    html WelcomeView = [hsx|\n"
               <>"         <div style=\"background-color: #657b83; padding: 2rem; color:hsla(196, 13%, 96%, 1); border-radius: 4px\">\n"
               <>"              <div style=\"max-width: 800px; margin-left: auto; margin-right: auto\">\n"
               <>"                  <h1 style=\"margin-bottom: 2rem; font-size: 2rem; font-weight: 300; border-bottom: 1px solid white; padding-bottom: 0.25rem; border-color: hsla(196, 13%, 60%, 1)\">\n"
               <>"                      IHP\n"
               <>"                  </h1>\n"
               <>"\n"
               <>"                  <h2 style=\"margin-top: 0; margin-bottom: 0rem; font-weight: 900; font-size: 3rem\">\n"
               <>"                      It's working!\n"
               <>"                  </h2>\n"
               <>"\n"
               <>"                  <p style=\"margin-top: 1rem; font-size: 1.75rem; font-weight: 600; color:hsla(196, 13%, 80%, 1)\">\n"
               <>"                     Your new application is up and running.\n"
               <>"                  </p>\n"
               <>"\n"
               <>"                  <p>\n"
               <>"                      <a\n"
               <>"                          href=\"https://ihp.digitallyinduced.com/Slack\"\n"
               <>"                          style=\"margin-top: 2rem; background-color: #268bd2; padding: 1rem; border-radius: 3px; color: hsla(205, 69%, 98%, 1); text-decoration: none; font-weight: bold; display: inline-block; box-shadow: 0 4px 6px hsla(205, 69%, 0%, 0.08); transition: box-shadow 0.2s; transition: transform 0.2s;\"\n"
               <>"                          target=\"_blank\"\n"
               <>"                      >Join our community on Slack!</a>\n"
               <>"                  </p>\n"
               <>"\n"
               <>"                  <a href=\"https://ihp.digitallyinduced.com/Guide/your-first-project.html\" style=\"margin-top: 2rem; background-color: #268bd2; padding: 1rem; border-radius: 3px; color: hsla(205, 69%, 98%, 1); text-decoration: none; font-weight: bold; display: inline-block; box-shadow: 0 4px 6px hsla(205, 69%, 0%, 0.08);  transition: box-shadow 0.2s; transition: transform 0.2s;\" target=\"_blank\">\n"
               <>"                     Learn the Next Steps in the Documentation\n"
               <>"                  </a>\n"
               <>"              </div>\n"
               <>"         </div>\n"
               <>"\n"
               <>"         <div style=\"max-width: 800px; margin-left: auto; margin-right: auto; margin-top: 4rem\">\n"
               <>"              <img src=\"/ihp-welcome-icon.svg\" alt=\"/ihp-welcome-icon\" style=\"width:100%;\">\n"
               <>"              <p style=\"color: hsla(196, 13%, 50%, 1); margin-top: 4rem\">\n"
               <>"                 You can modify this start page by making changes to \"./Web/View/Static/Welcome.hs\".\n"
               <>"              </p>\n"
               <>"         </div> \n"
               <>"|]"
  
          in
              [ EnsureDirectory { directory = applicationName }
              , EnsureDirectory { directory = applicationName <> "/Controller" }
              , EnsureDirectory { directory = applicationName <> "/View" }
              , EnsureDirectory { directory = applicationName <> "/View/Static" }
              , AddImport  { filePath = "Main.hs", fileContent = "import " <> applicationName <> ".FrontController" }
              , AddImport  { filePath = "Main.hs", fileContent = "import " <> applicationName <> ".Types" }
              , AddMountToFrontController { filePath = "Main.hs", applicationName = applicationName }
              , CreateFile { filePath = applicationName <> "/Types.hs", fileContent = typesHs }
              , CreateFile { filePath = applicationName <> "/Routes.hs", fileContent = routesHs }
              , CreateFile { filePath = applicationName <> "/FrontController.hs", fileContent = frontControllerHs }
              , CreateFile { filePath = applicationName <> "/Controller/Prelude.hs", fileContent = controllerPreludeHs }
              , CreateFile { filePath = applicationName <> "/View/Layout.hs", fileContent = viewLayoutHs }
              , CreateFile { filePath = applicationName <> "/View/Prelude.hs", fileContent = viewPreludeHs }
              , CreateFile { filePath = applicationName <> "/Controller/Static.hs", fileContent = welcomeControllerStaticHs }
              , CreateFile { filePath = applicationName <> "/View/Static/Welcome.hs", fileContent = welcomeViewStaticHs }
              ]
  