import { createContext, useContext, useEffect, useState } from "react";
import  { BaseDirectory, readTextFile, exists, writeTextFile, mkdir } from "@tauri-apps/plugin-fs";
import { ParamKeys, DefaultParams } from "./system_prompt";
import { path } from '@tauri-apps/api';
import { openPath } from '@tauri-apps/plugin-opener';

const dataContext=createContext();


const filePath= 'param.json';
const GlobalSettingsPath='./GlobalSettings.json';
const PrivateSettingsPath='./PrivateSettings.json';

export function DataProvider({children}) {

    const [data, setData] = useState(null);

    async function read(){

        try{

            // check exists
            const globalExists=await exists(GlobalSettingsPath, { baseDir: BaseDirectory.Resource });
            const privateExists=await exists(PrivateSettingsPath, { baseDir: BaseDirectory.Resource });
            console.log("GlobalSettings exists:", globalExists);
            console.log("PrivateSettings exists:", privateExists);
            if(!globalExists){
                // copy from public/default.json
                const res=await fetch('default.json');
                const defaultData=await res.json();
                await writeTextFile(GlobalSettingsPath, JSON.stringify(defaultData),
                     { baseDir: BaseDirectory.Resource });
                console.log("Default global settings written to", 
                    path(GlobalSettingsPath, { baseDir: BaseDirectory.Resource }));
            }
            if(!privateExists){
                await writeTextFile(PrivateSettingsPath, JSON.stringify({ id:13}), 
                    { baseDir: BaseDirectory.Resource });
                console.log("Empty private settings written to", 
                    path(PrivateSettingsPath, { baseDir: BaseDirectory.Resource }));
            }


            
           // const contents=await readTextFile(filePath, { baseDir: BaseDirectory.AppData });
           const contents=await readTextFile(GlobalSettingsPath, { baseDir: BaseDirectory.Resource });
           let output=await JSON.parse(contents);

           const private_contents=await readTextFile(PrivateSettingsPath, { baseDir: BaseDirectory.Resource });
           const private_output=await JSON.parse(private_contents);     
            output={...output, ...private_output};

            // check if all keys in ParamKeys are present in output
            const missingKeys = ParamKeys.filter(key => !output.hasOwnProperty(key));
            if(missingKeys.length > 0){
                console.warn("Missing keys in output:", missingKeys);
                // Fill missing keys with default values
                missingKeys.forEach(key => {
                    output[key] = DefaultParams[key] || ""; // Use params[key] as default value
                });
            }
            
            console.log("File read successfully:", output);

            return output; 

        }catch(error){
            console.error("Error reading file:", error);
            return null; // Return null if reading fails
        }
        
        
    }
    async function write(towrite){

        // let towrite=data;
        if(!towrite){
            const res=await fetch('default.json');
            towrite=await res.json();            
            setData(towrite);                     
        }
        
        if(towrite.id){
            try{
                await writeTextFile(PrivateSettingsPath, JSON.stringify({
                    id: towrite.id
                }), { baseDir: BaseDirectory.Resource });
                console.log("Private settings written successfully");
            }catch(error){
                console.error("Error writing private settings:", error);
            }
        }


        try{                
            const res_write=await writeTextFile(GlobalSettingsPath, JSON.stringify(towrite), { baseDir: BaseDirectory.Resource });
            console.log("File written successfully", GlobalSettingsPath, towrite);
        }catch(error){
            console.error("Error writing file:", error);
        }

    }

    useEffect(()=>{
        read().then(data_ => {
            if(data_){
                setData(data_);
            } else {
                write(); // Write default data if read fails
            }
        }).catch(error => {
            console.error("Error in useEffect:", error);
        });
    },[])


    return (
        <dataContext.Provider value={{
            data,
            read,
            write,              
            openFile: async () => {
                const folder = await path.resourceDir();
                // const file =  await path.join(folder, GlobalSettingsPath);
                await openPath(folder);
            },
        }}>
            {children}
        </dataContext.Provider>
    );
}

export function useData() {
    const context = useContext(dataContext);
    if (!context) {
        throw new Error("useData must be used within a DataProvider");
    }
    return context;
}