use clap::{Parser, Subcommand};
use serde::Deserialize;
use std::fs;
use std::path::PathBuf;

use liquid::parser::parse_liquid;
use liquid::optimizer::optimize_ast;
use liquid::generator::web::generate_web;
use liquid::generator::swift::generate_swift;
use liquid::generator::kotlin::generate_kotlin;
use liquid::generator::winui::generate_winui;
use liquid::dev_server::start_dev_server;

#[derive(Deserialize, Debug)]
struct TargetPaths {
    output: Option<PathBuf>,
    output_xaml: Option<PathBuf>,
    output_cs: Option<PathBuf>,
}

#[derive(Deserialize, Debug)]
struct Config {
    entry: PathBuf,
    targets: std::collections::HashMap<String, TargetPaths>,
}

#[derive(Parser)]
#[command(author, version, about = "Liquid framework compiler/transmutation engine", long_about = None)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Create a new Liquid multi-platform project with a structured workspace.
    Create {
        /// The name of the project directory to create
        name: String,
    },
    /// Compile (transmute) Liquid components.
    Build {
        /// Target platform: "web", "ios", "android", "windows", or "all". Defaults to "all".
        #[arg(default_value = "all")]
        target: String,

        /// Path to the input file (optional, read from liquid.config.json if not specified)
        input: Option<PathBuf>,

        /// Path to the output file (optional, read from liquid.config.json if not specified)
        #[arg(short, long)]
        output: Option<PathBuf>,
    },
    /// Start a local development server with Live Preview, Hot Reload, and Hot Restart.
    Dev {
        /// Path to the input file (optional, read from liquid.config.json if not specified)
        input: Option<PathBuf>,
    },
    /// Check the readiness of native build toolchains (dotnet, java, swiftc, etc).
    Doctor,
    /// Display the version of Liquid Framework.
    Version,
    /// Upgrade Liquid Framework to the latest or a specific version.
    Upgrade {
        /// Specific version to upgrade to (e.g. 0.1.2)
        version: Option<String>,
    },
}

fn main() {
    let cli = Cli::parse();

    match &cli.command {
        Commands::Version => {
            println!("Liquid Framework v{}", env!("CARGO_PKG_VERSION"));
        }
        Commands::Upgrade { version } => {
            let reset = "\x1b[0m";
            let cyan = "\x1b[36m";
            let green = "\x1b[32m";
            let red = "\x1b[31m";
            let bold = "\x1b[1m";

            println!("{}🚀 Upgrading Liquid Framework...{}", cyan, reset);

            let mut cmd = std::process::Command::new("cargo");
            cmd.arg("install").arg("liquid-transpiler").arg("--force");
            
            if let Some(ver) = version {
                println!("Target version: {}{}{}", bold, ver, reset);
                cmd.arg("--version").arg(ver);
            } else {
                println!("Target version: {}Latest{}", bold, reset);
            }

            // Inject MSVC paths for Windows so rustc linker works in pure PowerShell
            #[cfg(windows)]
            {
                let vs_base = "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC";
                let kits_inc_base = "C:\\Program Files (x86)\\Windows Kits\\10\\Include";
                let kits_lib_base = "C:\\Program Files (x86)\\Windows Kits\\10\\Lib";

                let mut msvc_version = String::new();
                if let Ok(entries) = std::fs::read_dir(vs_base) {
                    if let Some(entry) = entries.filter_map(Result::ok).map(|e| e.file_name().to_string_lossy().to_string()).max() {
                        msvc_version = entry;
                    }
                }

                let mut win_sdk_version = String::new();
                if let Ok(entries) = std::fs::read_dir(kits_inc_base) {
                    if let Some(entry) = entries.filter_map(Result::ok).map(|e| e.file_name().to_string_lossy().to_string()).max() {
                        win_sdk_version = entry;
                    }
                }

                if !msvc_version.is_empty() && !win_sdk_version.is_empty() {
                    let lib = format!("{}\\{}\\lib\\onecore\\x64;{}\\{}\\ucrt\\x64;{}\\{}\\um\\x64", vs_base, msvc_version, kits_lib_base, win_sdk_version, kits_lib_base, win_sdk_version);
                    let include = format!("{}\\{}\\include;{}\\{}\\ucrt;{}\\{}\\um;{}\\{}\\shared", vs_base, msvc_version, kits_inc_base, win_sdk_version, kits_inc_base, win_sdk_version, kits_inc_base, win_sdk_version);
                    cmd.env("LIB", lib);
                    cmd.env("INCLUDE", include);
                }
            }
            
            let status = cmd.status().unwrap_or_else(|e| {
                eprintln!("{}❌ Failed to execute cargo install: {}{}", red, e, reset);
                std::process::exit(1);
            });
            
            if status.success() {
                println!("\n{}✅ Successfully upgraded Liquid Framework!{}", green, reset);
                println!("Run {}liquid version{} to check the new version.", cyan, reset);
            } else {
                eprintln!("\n{}❌ Failed to upgrade Liquid Framework. Please check the error above.{}", red, reset);
            }
        }
        Commands::Doctor => {
            let reset = "\x1b[0m";
            let bold = "\x1b[1m";
            let green = "\x1b[32m";
            let red = "\x1b[31m";
            let cyan = "\x1b[36m";
            let yellow = "\x1b[33m";

            println!("{}💊 Liquid Framework Doctor{}", cyan, reset);
            println!("{}{}=================================================={}", bold, yellow, reset);
            println!("{}💧 Liquid Version : v{}{}\n", cyan, env!("CARGO_PKG_VERSION"), reset);
            
            println!("{}[ Native Toolchain Status ]{}", bold, reset);
            
            // Check .NET
            if let Ok(output) = std::process::Command::new("dotnet").arg("--version").output() {
                println!("  ✅ {}Windows (WinUI 3){}  : {}.NET SDK found ({}){}", bold, reset, green, String::from_utf8_lossy(&output.stdout).trim(), reset);
            } else {
                println!("  ❌ {}Windows (WinUI 3){}  : {}.NET SDK not found (Install .NET SDK){}", bold, reset, red, reset);
            }
            
            // Check Java / Kotlin
            if let Ok(output) = std::process::Command::new("java").arg("-version").output() {
                let stderr = String::from_utf8_lossy(&output.stderr);
                let version = stderr.lines().next().unwrap_or("Unknown version");
                println!("  ✅ {}Android (Compose){}  : {}Java found ({}){}", bold, reset, green, version, reset);
            } else {
                println!("  ❌ {}Android (Compose){}  : {}Java not found (Install Java/JDK){}", bold, reset, red, reset);
            }

            // Check Swift
            if let Ok(output) = std::process::Command::new("swiftc").arg("--version").output() {
                let stdout = String::from_utf8_lossy(&output.stdout);
                let version = stdout.lines().next().unwrap_or("Unknown version");
                println!("  ✅ {}iOS (SwiftUI){}      : {}Swift found ({}){}", bold, reset, green, version, reset);
            } else {
                println!("  ❌ {}iOS (SwiftUI){}      : {}Swift not found (Install Xcode / Swift){}", bold, reset, red, reset);
            }

            // Check Web
            if let Ok(output) = std::process::Command::new("cargo").arg("--version").output() {
                println!("  ✅ {}Web (WASM){}         : {}Cargo found ({}){}", bold, reset, green, String::from_utf8_lossy(&output.stdout).trim(), reset);
            } else {
                println!("  ❌ {}Web (WASM){}         : {}Cargo not found (Install Rust){}", bold, reset, red, reset);
            }
            
            println!("{}{}=================================================={}", bold, yellow, reset);
            println!("{}Doctor check completed.{}", green, reset);
            println!("\n{}✨ Created by Panca Nugraha✨{}", cyan, reset);
        }
        Commands::Create { name } => {
            println!("Creating new Liquid project: {}...", name);
            if let Err(err) = create_project(name) {
                eprintln!("Error creating project: {}", err);
                std::process::exit(1);
            }
            println!("Successfully created project '{}'. Check the README.md to start!", name);
        }
        Commands::Build { target, input, output } => {
            let config_path = PathBuf::from("liquid.config.json");
            let config = if config_path.exists() {
                let config_str = fs::read_to_string(&config_path).unwrap_or_else(|err| {
                    eprintln!("Error reading liquid.config.json: {}", err);
                    std::process::exit(1);
                });
                let parsed: Config = serde_json::from_str(&config_str).unwrap_or_else(|err| {
                    eprintln!("Error parsing liquid.config.json: {}", err);
                    std::process::exit(1);
                });
                Some(parsed)
            } else {
                None
            };

            let input_file = match input {
                Some(file) => file.clone(),
                None => {
                    if let Some(ref cfg) = config {
                        cfg.entry.clone()
                    } else {
                        eprintln!("Error: No input file specified and liquid.config.json not found.");
                        std::process::exit(1);
                    }
                }
            };

            let src_code = fs::read_to_string(&input_file).unwrap_or_else(|err| {
                eprintln!("Error reading input file {}: {}", input_file.display(), err);
                std::process::exit(1);
            });

            // 1. Parsing
            let ast = parse_liquid(&src_code).unwrap_or_else(|err| {
                eprintln!("Parsing Error: {}", err);
                std::process::exit(1);
            });

            // 2. Optimizing
            let optimized_ast = optimize_ast(ast);

            let run_build = |t: &str, out: &Option<PathBuf>| {
                match t {
                    "web" => {
                        let code = generate_web(&optimized_ast);
                        write_output(out, &code);
                    }
                    "ios" | "swift" => {
                        let code = generate_swift(&optimized_ast);
                        write_output(out, &code);
                    }
                    "android" | "kotlin" => {
                        let code = generate_kotlin(&optimized_ast);
                        write_output(out, &code);
                    }
                    "windows" | "winui" => {
                        let code = generate_winui(&optimized_ast);
                        if let Some(out_p) = out {
                            if out_p.to_string_lossy() == "windows_dummy" {
                                if let Some(ref cfg) = config {
                                    if let Some(paths) = cfg.targets.get("windows") {
                                        let xaml_path = paths.output_xaml.clone();
                                        let cs_path = paths.output_cs.clone();
                                        if xaml_path.is_some() && cs_path.is_some() {
                                            let parts: Vec<&str> = code.split("/* === C# Code-Behind (Counter.xaml.cs) === */").collect();
                                            if parts.len() == 2 {
                                                let xaml_parts: Vec<&str> = parts[0].split("<!-- === XAML (Counter.xaml) === -->\n").collect();
                                                let common_helpers = xaml_parts[0];
                                                let xaml = xaml_parts.get(1).unwrap_or(&"");
                                                let cs_code_behind = parts[1].trim_start();
                                                
                                                let cs_part = format!("{}\n{}", common_helpers, cs_code_behind);
                                                let xaml_part = xaml.to_string();
                                                
                                                let xp = xaml_path.unwrap();
                                                let cp = cs_path.unwrap();
                                                
                                                fs::write(&xp, xaml_part).unwrap();
                                                fs::write(&cp, cs_part).unwrap();
                                                println!("Successfully wrote XAML to {} and C# to {}", xp.display(), cp.display());
                                                
                                                // Use vswhere to find Visual Studio's MSBuild to avoid .NET 8/9 CLI PriGen bug
                                                let vswhere_path = "C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\vswhere.exe";
                                                let mut msbuild_path = None;
                                                if std::path::Path::new(vswhere_path).exists() {
                                                    if let Ok(output) = std::process::Command::new(vswhere_path)
                                                        .args(&["-latest", "-requires", "Microsoft.Component.MSBuild", "-find", "MSBuild\\**\\Bin\\MSBuild.exe"])
                                                        .output() {
                                                        let path = String::from_utf8_lossy(&output.stdout).trim().to_string();
                                                        if !path.is_empty() && std::path::Path::new(&path).exists() {
                                                            msbuild_path = Some(path);
                                                        }
                                                    }
                                                }
                                                
                                                let mut cmd;
                                                if let Some(msb) = msbuild_path {
                                                    println!("Invoking MSBuild to compile Windows executable...");
                                                    cmd = std::process::Command::new(msb);
                                                    cmd.arg("-restore").arg("/p:Configuration=Release");
                                                } else {
                                                    println!("Invoking dotnet build to compile Windows executable (MSBuild not found, might fail on .NET 9)...");
                                                    cmd = std::process::Command::new("dotnet");
                                                    cmd.arg("build").arg("-c").arg("Release");
                                                }
                                                
                                                if let Some(parent) = xp.parent() {
                                                    cmd.current_dir(parent);
                                                }
                                                
                                                let status = cmd.status().unwrap_or_else(|e| {
                                                    eprintln!("Failed to execute build command: {}", e);
                                                    std::process::exit(1);
                                                });
                                                
                                                if status.success() {
                                                    println!("Successfully compiled Windows native executable!");
                                                    if let Some(parent) = xp.parent() {
                                                        println!("Executable is located in: {}/bin/Release/net8.0-windows10.0.19041.0/win-x64/LiquidApp.exe", parent.display());
                                                    }
                                                } else {
                                                    eprintln!("Error: Windows native build failed.");
                                                }
                                                
                                                return;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        write_output(out, &code);
                    }
                    _ => {
                        eprintln!("Unknown target: {}", t);
                        std::process::exit(1);
                    }
                }
            };

            let target_str = target.to_lowercase();
            if target_str == "all" {
                if let Some(ref cfg) = config {
                    for (t_name, paths) in &cfg.targets {
                        println!("Building target: {}...", t_name);
                        let out_path = if t_name == "windows" {
                            Some(PathBuf::from("windows_dummy"))
                        } else {
                            paths.output.clone()
                        };
                        run_build(t_name, &out_path);
                    }
                } else {
                    eprintln!("Error: 'all' target requires liquid.config.json configuration file.");
                    std::process::exit(1);
                }
            } else {
                let out_path = match output {
                    Some(out) => Some(out.clone()),
                    None => {
                        if let Some(ref cfg) = config {
                            let cfg_key = match target_str.as_str() {
                                "swift" => "ios",
                                "kotlin" => "android",
                                "winui" => "windows",
                                _ => &target_str
                            };
                            if let Some(paths) = cfg.targets.get(cfg_key) {
                                if cfg_key == "windows" {
                                    Some(PathBuf::from("windows_dummy"))
                                } else {
                                    paths.output.clone()
                                }
                            } else {
                                None
                            }
                        } else {
                            None
                        }
                    }
                };
                run_build(&target_str, &out_path);
            }
        }
        Commands::Dev { input } => {
            let config_path = PathBuf::from("liquid.config.json");
            let config = if config_path.exists() {
                let config_str = fs::read_to_string(&config_path).unwrap_or_else(|err| {
                    eprintln!("Error reading liquid.config.json: {}", err);
                    std::process::exit(1);
                });
                let parsed: Config = serde_json::from_str(&config_str).unwrap_or_else(|err| {
                    eprintln!("Error parsing liquid.config.json: {}", err);
                    std::process::exit(1);
                });
                Some(parsed)
            } else {
                None
            };

            let input_file = match input {
                Some(file) => file.clone(),
                None => {
                    if let Some(ref cfg) = config {
                        cfg.entry.clone()
                    } else {
                        eprintln!("Error: No input file specified and liquid.config.json not found.");
                        std::process::exit(1);
                    }
                }
            };

            start_dev_server(input_file);
        }
    }
}

fn write_output(path: &Option<PathBuf>, content: &str) {
    if let Some(out_p) = path {
        if out_p.to_string_lossy() == "windows_dummy" {
            return;
        }
        fs::write(out_p, content).unwrap_or_else(|err| {
            eprintln!("Error writing output {}: {}", out_p.display(), err);
            std::process::exit(1);
        });
        println!("Successfully wrote output to {}", out_p.display());
    } else {
        println!("{}", content);
    }
}

/// Helper function to create the directories and template files for a new project.
fn create_project(project_name: &str) -> std::io::Result<()> {
    let root = PathBuf::from(project_name);
    fs::create_dir_all(root.join("src"))?;
    fs::create_dir_all(root.join("platforms/web/src"))?;
    fs::create_dir_all(root.join("platforms/ios"))?;
    fs::create_dir_all(root.join("platforms/android/app/src/main/java/com/example/app"))?;
    fs::create_dir_all(root.join("platforms/windows"))?;

    // 1. liquid.config.json
    let config_content = format!(r#"{{
  "project_name": "{}",
  "entry": "src/main.liq",
  "targets": {{
    "web": {{
      "output": "platforms/web/src/lib.rs"
    }},
    "ios": {{
      "output": "platforms/ios/AppView.swift"
    }},
    "android": {{
      "output": "platforms/android/app/src/main/java/com/example/app/Counter.kt"
    }},
    "windows": {{
      "output_xaml": "platforms/windows/Counter.xaml",
      "output_cs": "platforms/windows/Counter.xaml.cs"
    }}
  }}
}}
"#, project_name);
    fs::write(root.join("liquid.config.json"), config_content)?;

    // 2. README.md
    let readme_content = r#"# Liquid Multi-Platform Starter Project

This is a clean, pre-structured workspace for building cross-platform native applications using the **Liquid Framework**.

## Workspace Structure

```
├── liquid.config.json   # Configuration for build targets
├── README.md            # Getting started guide
├── src/
│   └── main.liq         # The main entry component code
└── platforms/
    ├── web/             # Web wrapper project (Rust/WASM + HTML)
    │   ├── Cargo.toml
    │   ├── index.html
    │   └── src/
    │       └── lib.rs   # Target for compiler output
    ├── ios/             # iOS wrapper project (Swift/SwiftUI)
    │   ├── AppView.swift# Target for compiler output
    │   └── App.swift    # App startup entry
    ├── android/         # Android wrapper project (Kotlin/Compose)
    │   └── app/
    │       └── src/
    │           └── main/
    │               └── java/
    │                   └── com/
    │                       └── example/
    │                           └── app/
    │                               ├── Counter.kt     # Target for compiler output
    │                               └── MainActivity.kt# Compose Activity loader
    └── windows/         # Windows Desktop wrapper project (C#/WinUI 3)
        ├── MainWindow.xaml.cs # Host window code-behind
        ├── Counter.xaml       # Target for compiler XAML
        └── Counter.xaml.cs    # Target for compiler C# Code-behind
```

## How to Build

Thanks to `liquid.config.json`, compilation is fully automated. You do not need to specify input or output paths. Simply run the following commands from the root of your workspace:

### Build All Targets
To compile for all target platforms defined in `liquid.config.json` simultaneously:
```bash
liquid build
```

### Build Web (WASM)
```bash
liquid build web
```

### Build iOS
```bash
liquid build ios
```

### Build Android
```bash
liquid build android
```

### Build Windows (WinUI 3)
This automatically generates and splits the XAML markup and C# code-behind files:
```bash
liquid build windows
```

### Local Live Development (Hot Reload & Emulator Dashboard)
To run a local live-reloaded simulator server in the browser:
```bash
liquid dev
```
"#;
    fs::write(root.join("README.md"), readme_content)?;

    // 3. src/main.liq
    let main_liq_content = r#"import 'liquid:ui';

class Counter extends Component {
  int count = 0;
  String title = "Liquid Counter";

  void increment() {
    count++;
  }

  @override
  Widget build() {
    return Column(
      alignment: Alignment.center,
      spacing: 16.0,
      children: [
        Text(
          "$title: $count",
          style: TextStyle(
            fontSize: 24.0,
            weight: FontWeight.bold
          )
        ),
        Button(
          label: "Increment",
          onPressed: increment
        )
      ]
    );
  }
}
"#;
    fs::write(root.join("src/main.liq"), main_liq_content)?;

    // 4. platforms/web/Cargo.toml
    let cargo_toml_content = r#"[package]
name = "liquid-web-app"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"
web-sys = { version = "0.3", features = ["window", "document", "Element", "HtmlElement"] }
"#;
    fs::write(root.join("platforms/web/Cargo.toml"), cargo_toml_content)?;

    // 5. platforms/web/index.html
    let index_html_content = r#"<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Liquid Web App</title>
    <style>
        body {
            margin: 0;
            padding: 40px;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            background-color: #121212;
            color: #ffffff;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
        }
        button {
            padding: 12px 24px;
            font-size: 16px;
            font-weight: 600;
            background: linear-gradient(135deg, #6366f1, #4f46e5);
            color: white;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            transition: transform 0.1s ease, filter 0.2s ease;
        }
        button:hover {
            filter: brightness(1.1);
        }
        button:active {
            transform: scale(0.98);
        }
    </style>
</head>
<body>
    <div id="app"></div>
    <script type="module">
        import init, { Counter } from './pkg/liquid_web_app.js';
        async function run() {
            await init();
            const counter = new Counter();
            counter.render("app");
        }
        run();
    </script>
</body>
</html>
"#;
    fs::write(root.join("platforms/web/index.html"), index_html_content)?;

    // 6. platforms/ios/App.swift
    let app_swift_content = r#"import SwiftUI

@main
struct LiquidApp: App {
    var body: some Scene {
        WindowGroup {
            Counter()
        }
    }
}
"#;
    fs::write(root.join("platforms/ios/App.swift"), app_swift_content)?;

    // 7. platforms/android/app/src/main/java/com/example/app/MainActivity.kt
    let main_activity_content = r#"package com.example.app

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Counter()
                }
            }
        }
    }
}
"#;
    fs::write(root.join("platforms/android/app/src/main/java/com/example/app/MainActivity.kt"), main_activity_content)?;

    // 8. platforms/windows/ Windows Native Project Scaffold
    let csproj_content = r#"<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
    <RootNamespace>LiquidApp</RootNamespace>
    <Platforms>x86;x64;ARM64</Platforms>
    <RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
    <UseWinUI>true</UseWinUI>
    <WindowsPackageType>None</WindowsPackageType>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240428000" />
    <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.3233" />
  </ItemGroup>
</Project>
"#;
    fs::write(root.join("platforms/windows/LiquidApp.csproj"), csproj_content)?;

    let app_xaml_content = r#"<Application
    x:Class="LiquidApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
"#;
    fs::write(root.join("platforms/windows/App.xaml"), app_xaml_content)?;

    let app_cs_content = r#"using Microsoft.UI.Xaml;

namespace LiquidApp
{
    public partial class App : Application
    {
        public App()
        {
            this.InitializeComponent();
        }

        protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
        {
            m_window = new MainWindow();
            m_window.Activate();
        }

        private Window m_window;
    }
}
"#;
    fs::write(root.join("platforms/windows/App.xaml.cs"), app_cs_content)?;

    let main_window_xaml_content = r#"<Window
    x:Class="LiquidApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:LiquidApp"
    Title="Liquid Framework App">
    
    <Grid>
        <!-- The content is set in Code-Behind -->
    </Grid>
</Window>
"#;
    fs::write(root.join("platforms/windows/MainWindow.xaml"), main_window_xaml_content)?;

    let main_window_content = r#"using Microsoft.UI.Xaml;

namespace LiquidApp
{
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
            this.Content = new Counter();
        }
    }
}
"#;
    fs::write(root.join("platforms/windows/MainWindow.xaml.cs"), main_window_content)?;

    Ok(())
}
