import { Provide, Scope, ScopeEnum, Logger, Init } from '@midwayjs/core';
import { ILogger } from '@midwayjs/logger';
import * as fs from 'fs/promises';
import * as path from 'path';
import * as crypto from 'crypto';
import { resolveDataDir } from '../../../comm/data-dir.js';

export interface SkillHubLockfile {
  version: 1;
  skills: Record<string, { version: string; fingerprint: string; installedAt: number }>;
}

export interface SkillOrigin {
  version: 1;
  source: string;
  url: string;
  branch?: string;
  commitHash: string;
  installedAt: string;
}

@Provide()
@Scope(ScopeEnum.Singleton)
export class SkillRegistryService {
  @Logger()
  logger: ILogger;

  private hubDir: string;
  private originsDir: string;
  private lockfilePath: string;

  @Init()
  async init() {
    const root = resolveDataDir();
    this.hubDir = path.resolve(root, '.skillhub');
    this.originsDir = path.join(this.hubDir, 'origins');
    this.lockfilePath = path.join(this.hubDir, 'lock.json');
    await fs.mkdir(this.originsDir, { recursive: true });
  }

  async readLockfile(): Promise<SkillHubLockfile> {
    try {
      const raw = await fs.readFile(this.lockfilePath, 'utf-8');
      return JSON.parse(raw);
    } catch {
      return { version: 1, skills: {} };
    }
  }

  async writeLockfile(lockfile: SkillHubLockfile): Promise<void> {
    await fs.writeFile(this.lockfilePath, JSON.stringify(lockfile, null, 2), 'utf-8');
  }

  async writeOrigin(name: string, origin: SkillOrigin): Promise<void> {
    const filePath = path.join(this.originsDir, `${name}.json`);
    await fs.writeFile(filePath, JSON.stringify(origin, null, 2), 'utf-8');
  }

  async readOrigin(name: string): Promise<SkillOrigin | null> {
    try {
      const filePath = path.join(this.originsDir, `${name}.json`);
      const raw = await fs.readFile(filePath, 'utf-8');
      return JSON.parse(raw);
    } catch {
      return null;
    }
  }

  async removeOrigin(name: string): Promise<void> {
    try {
      await fs.unlink(path.join(this.originsDir, `${name}.json`));
    } catch { /* ignore */ }
  }

  async computeFingerprint(skillDir: string): Promise<string> {
    const skillMdPath = path.join(skillDir, 'SKILL.md');
    const content = await fs.readFile(skillMdPath, 'utf-8');
    return crypto.createHash('sha256').update(content).digest('hex');
  }
}
