import { ref } from 'vue';
import Papa from 'papaparse';

interface SimulationState {
    currentTime: number; // 0 to 24 (hours)
    isPlaying: boolean;
    speed: number;
    day: number;
    totalSeconds: number;
    totalConsumption: number;
    totalGeneration: number;
    dataBaseUrl: string;
    brightness: number;
    simulationMode: 'simulated' | 'live';
    maxZoom: number;
    zoomSensitivity: number;
    buildings: BuildingDefinition[];
}

export interface BuildingDefinition {
    id: string;
    type: string;
    csvPath: string;
}

// ...

interface BuildingData {
    id: string;
    type: string;
    description: string;
    consumption: number | string;
    generation: number | string;
    iot: string;
    csvPath?: string;
    energyData?: any[];
    uiX?: number;
    uiY?: number;
}

// (State initialization is already correct with buildings..., just ensure the types match)

// ...


// Initialize with current real-world time
const now = new Date();
const startOfYear = new Date(now.getFullYear(), 0, 0);
const diff = now.getTime() - startOfYear.getTime();
const oneDay = 1000 * 60 * 60 * 24;
const dayOfYear = Math.floor(diff / oneDay);


const state = ref<SimulationState>({
    currentTime: now.getHours() + now.getMinutes() / 60,
    isPlaying: false,
    speed: 1,
    day: dayOfYear,
    totalSeconds: 0,
    totalConsumption: 0,
    totalGeneration: 0,
    dataBaseUrl: '',
    brightness: 1.0,
    simulationMode: 'simulated',
    maxZoom: 120,
    zoomSensitivity: 5,
    buildings: [
        { id: 'H01', type: 'house', csvPath: 'data/H01.csv' },
        { id: 'H02', type: 'factory', csvPath: 'data/H02.csv' },
        { id: 'H03', type: 'office', csvPath: 'data/H03.csv' },
        { id: 'H04', type: 'shop', csvPath: 'data/H04.csv' },
        { id: 'H05', type: 'house', csvPath: 'data/H05.csv' },
        { id: 'H06', type: 'house', csvPath: 'data/H06.csv' },
        { id: 'H07', type: 'house', csvPath: 'data/H07.csv' },
        { id: 'H08', type: 'shop', csvPath: 'data/H08.csv' },
        { id: 'H09', type: 'shop', csvPath: 'data/H09.csv' },
        { id: 'H10', type: 'house', csvPath: 'data/H10.csv' },
        { id: 'H11', type: 'house', csvPath: 'data/H11.csv' },
        { id: 'H12', type: 'house', csvPath: 'data/H12.csv' },
        { id: 'H13', type: 'house', csvPath: 'data/H13.csv' },
        { id: 'H14', type: 'house', csvPath: 'data/H14.csv' },
    ]
});
const selectedBuilding = ref<BuildingData | null>(null);

export const useSimulation = () => {

    const togglePlay = () => {
        state.value.isPlaying = !state.value.isPlaying;
    };

    const setSpeed = (speed: number) => {
        state.value.speed = speed;
    };

    const setBrightness = (val: number) => {
        state.value.brightness = val;
    };

    const setSimulationMode = (mode: 'simulated' | 'live') => {
        state.value.simulationMode = mode;
        if (mode === 'live') {
            state.value.isPlaying = true; // Auto-play in live? Or just simple update.
        }
    };

    const setMaxZoom = (val: number) => {
        state.value.maxZoom = val;
    };

    const setZoomSensitivity = (val: number) => {
        state.value.zoomSensitivity = val;
    };

    const setDataBaseUrl = (url: string) => {
        state.value.dataBaseUrl = url;
    };

    const loadBuildingData = (_buildingId: string, csvPath: string) => {
        // Construct full URL
        let fullPath = csvPath;
        if (state.value.dataBaseUrl) {
            // Check for slash consistency
            const base = state.value.dataBaseUrl.endsWith('/') ? state.value.dataBaseUrl : state.value.dataBaseUrl + '/';
            // If csvPath starts with data/, we might keep it or not. The user plan said prepending.
            // If base is http://.../ and path is data/H01.csv -> http://.../data/H01.csv. This seems correct.
            fullPath = base + csvPath;
        }

        // console.log(`Loading data for ${_buildingId} from ${fullPath}`);
        return new Promise((resolve, reject) => {
            Papa.parse(fullPath, {
                download: true,
                header: true,
                dynamicTyping: true,
                complete: (results) => {
                    resolve(results.data);
                },
                error: (err) => {
                    reject(err);
                }
            });
        });
    };

    const updateTime = (delta: number) => {
        if (state.value.simulationMode === 'live') {
            const now = new Date();
            state.value.currentTime = now.getHours() + now.getMinutes() / 60 + now.getSeconds() / 3600;
            // Day logic could be complex for real world, let's just ignore or keep rough sync
        } else {
            if (!state.value.isPlaying) return;

            state.value.currentTime += delta * state.value.speed;
            if (state.value.currentTime >= 24) {
                state.value.currentTime = 0;
                state.value.day++;
            }
        }

        // --- Simulated Community Energy Logic ---
        const time = state.value.currentTime;

        // Consumption Curve: Base load + Evening Peak (18-22)
        // Base Community Load ~4000kW
        let load = 4000;
        // Peak
        if (time > 17 && time < 23) {
            load += 2000 * Math.sin(((time - 17) / 6) * Math.PI);
        }
        // Morning spike
        if (time > 6 && time < 9) {
            load += 1000 * Math.sin(((time - 6) / 3) * Math.PI);
        }

        // Generation Curve: Based on simplified Sun Elevation
        // Simple Parabola from 6am to 6pm
        let gen = 0;
        if (time > 6 && time < 18) {
            // Peak at 12
            const sunFactor = Math.sin(((time - 6) / 12) * Math.PI);
            gen = 3500 * sunFactor; // Max 3500kW generation
        }

        state.value.totalConsumption = Math.floor(load);
        state.value.totalGeneration = Math.floor(gen);
    };

    const addBuilding = (def: BuildingDefinition) => {
        state.value.buildings.push(def);
    };

    return {
        state,
        selectedBuilding,
        togglePlay,
        setSpeed,
        loadBuildingData,
        updateTime,
        setDataBaseUrl,
        setBrightness,
        setSimulationMode,
        setMaxZoom,
        setZoomSensitivity,
        addBuilding
    };
};
