#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <chrono>
#include <thread>
#include <algorithm>
#include <numeric>
#include <memory>
#include <iomanip>

// ==========================================
// 宏观定义区：赋予系统宏大的叙事背景
// ==========================================
#define SYSTEM_TITLE "基于热力学第二定律的流体熵增与相变观测系统"
#define VERSION_CODENAME "ENTROPY_MASTER_3000"
#define PHILOSOPHY_QUOTE "能量守恒，但意义不守恒"

// 定义一些毫无用处但在物理书上很常见的常量
namespace PhysicalConstants {
	const double BOLTZMANN = 1.380649e-23; // 玻尔兹曼常数
	const double AVOGADRO = 6.02214076e23; // 阿伏伽德罗常数
	const double PI = 3.14159265358979;
	const double EULER = 2.71828182845904;
}

// ==========================================
// 抽象层：定义“被观察对象”的接口
// ==========================================
class IObservable {
public:
	virtual void updateState(double value) = 0;
	virtual double getState() const = 0;
	virtual ~IObservable() = default;
};

// ==========================================
// 策略模式：定义加热的“算法”
// ==========================================
class IHeatingStrategy {
public:
	virtual void executeHeating(double& temp) = 0;
	virtual ~IHeatingStrategy() = default;
};

// 策略A：线性加热（枯燥但稳定）
class LinearHeating : public IHeatingStrategy {
public:
	void executeHeating(double& temp) override {
		temp += 0.5;
	}
};

// 策略B：正弦波动加热（模拟不稳定的电压）
class SinusoidalHeating : public IHeatingStrategy {
private:
	int tick;
public:
	SinusoidalHeating() : tick(0) {}
	void executeHeating(double& temp) override {
		tick++;
		// 加上一个微小的正弦波动，假装电压不稳
		temp += 0.5 + (std::sin(tick * 0.1) * 0.05);
	}
};

// ==========================================
// 核心类：水分子集合体
// ==========================================
class WaterMoleculeCluster : public IObservable {
private:
	std::vector<double> kinetic_energies;
	double current_temp;
	std::shared_ptr<IHeatingStrategy> strategy;
	
public:
	WaterMoleculeCluster() : current_temp(20.0) {
		// 初始化一万个水分子的动能，纯粹为了消耗内存和增加复杂度
		kinetic_energies.resize(10000);
		std::iota(kinetic_energies.begin(), kinetic_energies.end(), 0.0);
		
		// 默认使用正弦加热，显得更高级
		strategy = std::make_shared<SinusoidalHeating>();
	}
	
	// 设置加热策略
	void setStrategy(std::shared_ptr<IHeatingStrategy> s) {
		strategy = s;
	}
	
	// 实现接口方法
	void updateState(double value) override {
		current_temp = value;
	}
	
	double getState() const override {
		return current_temp;
	}
	
	// 极其复杂的熵增计算
	double calculateEntropy() const {
		double entropy = 0.0;
		// 这是一个O(N)的循环，用来模拟分子混乱度
		for (double ke : kinetic_energies) {
			if (ke > 0) {
				entropy += PhysicalConstants::BOLTZMANN * std::log(ke + 1);
			}
		}
		return entropy * 1e22; // 放大倍数，否则全是0
	}
	
	// 核心加热逻辑
	void heatUpProcess() {
		if (strategy) {
			strategy->executeHeating(current_temp);
		}
		
		// 模拟热传导：更新所有分子的动能
		std::for_each(kinetic_energies.begin(), kinetic_energies.end(), [this](double& ke) {
			ke = (current_temp + 273.15) * PhysicalConstants::BOLTZMANN * (1.0 + (std::rand() % 100) / 1000.0);
		});
	}
};

// ==========================================
// 工厂模式：生产“观测报告”
// ==========================================
class ReportFactory {
public:
	static std::string generateLog(double temp, double entropy) {
		std::ostringstream oss;
		oss << std::fixed << std::setprecision(4);
		
		if (temp < 50) {
			oss << "[低温态] 温度: " << temp << "K (归一化熵: " << entropy << ") - 分子在沉睡";
		} else if (temp < 90) {
			oss << "[亚临界态] 温度: " << temp << "K (归一化熵: " << entropy << ") - 分子开始躁动";
		} else {
			oss << "[相变临界] 温度: " << temp << "K (归一化熵: " << entropy << ") - 突破液态束缚！";
		}
		return oss.str();
	}
};

// ==========================================
// 主控类：系统的总指挥
// ==========================================
class ThermodynamicController {
private:
	WaterMoleculeCluster water;
	bool is_running;
	
public:
	ThermodynamicController() : is_running(false) {}
	
	void startObservation() {
		is_running = true;
		std::cout << ">>> 初始化热力学观测环境..." << std::endl;
		
		// 假装在进行复杂的握手协议
		for(int i=0; i<3; ++i) {
			std::this_thread::sleep_for(std::chrono::milliseconds(300));
			std::cout << ">>> 连接传感器 " << (i+1) << "/3" << std::endl;
		}
		
		std::cout << ">>> 观测开始。" << std::endl;
		
		while (is_running) {
			water.heatUpProcess();
			double temp = water.getState();
			double entropy = water.calculateEntropy();
			
			// 打印报告
			std::cout << "\r" << ReportFactory::generateLog(temp, entropy);
			
			// 终止条件
			if (temp >= 100.0) {
				std::cout << "\n>>> [警报] 相变完成。水已沸腾。" << std::endl;
				is_running = false;
			}
			
			// 模拟采样率延迟
			std::this_thread::sleep_for(std::chrono::milliseconds(50));
		}
	}
};

// ==========================================
// 入口点：一切奇点的开始
// ==========================================
int main() {
	// 设置控制台标题（纯视觉优化）
	system("title 基于热力学第二定律的流体熵增与相变观测系统 v3.0");
	
	std::cout << "==================================================" << std::endl;
	std::cout << "  " << SYSTEM_TITLE << std::endl;
	std::cout << "  代号: " << VERSION_CODENAME << std::endl;
	std::cout << "  格言: " << PHILOSOPHY_QUOTE << std::endl;
	std::cout << "==================================================" << std::endl;
	
	// 实例化控制器
	ThermodynamicController controller;
	
	// 启动观测
	try {
		controller.startObservation();
	} catch (...) {
		std::cout << "\n[错误] 宇宙发生了未知异常。" << std::endl;
	}
	
	std::cout << ">>> 观测结束。请享用您的熵增产物。" << std::endl;
	
	// 暂停
	std::cin.get();
	return 0;
}
