import { app } from "electron";
import fs from "node:fs/promises";
import path from "node:path";
import type { AppConfig } from "../../shared/types";

export const DEFAULT_CONFIG: AppConfig = {
  environmentName: "test-gateway",
  baseUrl: "http://192.168.1.242:8080",
  tenantCode: "zswl",
  tenantDomain: "192.168.0.11",
  deepSeek: {
    enabled: true,
    baseURL: "https://api.deepseek.com",
    apiKey: process.env.DEEPSEEK_API_KEY ?? "",
    model: "deepseek-v4-pro",
    reasoningEffort: "high"
  },
  database: {
    enabled: false,
    host: "",
    port: 3306,
    database: "smqjh_pms",
    username: "",
    password: ""
  },
  mcp: {
    enabled: true,
    host: "192.168.1.20",
    port: 8765,
    path: "/mcp",
    authToken: "",
    allowExternal: true
  },
  auth: {
    tokenPath: "/smqjh-auth/oauth2/token",
    clientId: "mall-admin",
    clientSecret: "123456",
    grantType: "password"
  },
  requestTimeoutMs: 15000,
  dryRun: true
};

function mergeConfig(base: AppConfig, patch: Partial<AppConfig>): AppConfig {
  return {
    ...base,
    ...patch,
    deepSeek: {
      ...base.deepSeek,
      ...(patch.deepSeek ?? {})
    },
    database: {
      ...base.database,
      ...(patch.database ?? {})
    },
    mcp: {
      ...base.mcp,
      ...(patch.mcp ?? {})
    },
    auth: {
      ...base.auth,
      ...(patch.auth ?? {})
    }
  };
}

export class ConfigStore {
  private config: AppConfig = DEFAULT_CONFIG;

  async load(): Promise<AppConfig> {
    try {
      const raw = await fs.readFile(this.filePath(), "utf8");
      this.config = mergeConfig(DEFAULT_CONFIG, JSON.parse(raw) as Partial<AppConfig>);
      if (!this.config.tenantCode.trim()) {
        this.config.tenantCode = DEFAULT_CONFIG.tenantCode;
        await this.save(this.config);
      }
    } catch (error) {
      this.config = DEFAULT_CONFIG;
      await this.save(this.config);
    }

    return this.config;
  }

  get(): AppConfig {
    return this.config;
  }

  async save(patch: Partial<AppConfig>): Promise<AppConfig> {
    this.config = mergeConfig(this.config, patch);
    await fs.mkdir(path.dirname(this.filePath()), { recursive: true });
    await fs.writeFile(this.filePath(), JSON.stringify(this.config, null, 2), "utf8");
    return this.config;
  }

  filePath(): string {
    return path.join(app.getPath("userData"), "config.json");
  }
}
