import { appDataDir, join } from '@tauri-apps/api/path'
import { writeTextFile, readTextFile, exists, createDir, removeFile } from '@tauri-apps/api/fs'
import type { StorageInterface } from './StorageInterface'
import { ServiceBase } from './ServiceBase'

export class TauriFileStorageService extends ServiceBase implements StorageInterface {
  constructor() {
    super()
  }

  private async getFilePath(filename: string, dir: string = 'data'): Promise<string> {
    const userAppDir = await appDataDir()
    await this.ensureDirExists(await join(userAppDir, dir))
    return await join(userAppDir, dir, filename)
  }

  async saveUserDataText(fileName: string, content: any) {
    const filePath = await this.getFilePath(fileName + '.txt')
    await this.write(filePath, content, false)
  }

  async saveUserDataJson(fileName: string, content: any) {
    const filePath = await this.getFilePath(fileName + '.json')
    await this.write(filePath, content, true)
  }

  async readUserDataText(fileName: string) {
    const filePath = await this.getFilePath(fileName + '.txt')
    const content = await this.read(filePath, false)
    return content
  }

  async readUserDataJson(fileName: string) {
    const filePath = await this.getFilePath(fileName + '.json')
    const content = await this.read(filePath, true)
    return content
  }

  async saveConfigData(content: any) {
    const filePath = await this.getFilePath('config.json')
    await this.write(filePath, content)
  }

  async readConfigData() {
    const filePath = await this.getFilePath('config.json')
    const content = await this.read(filePath, true)
    return content
  }

  async deleteUserDataText(fileName: string) {
    const filePath = await this.getFilePath(fileName + '.txt')
    await removeFile(filePath)
  }

  async deleteUserDataJson(fileName: string) {
    const filePath = await this.getFilePath(fileName + '.json')
    await removeFile(filePath)
  }

  private async ensureDirExists(dir: string) {
    const dirExists = await exists(dir)
    if (!dirExists) {
      await createDir(dir, { recursive: true })
    }
  }

  private async write(filePath: string, content: any, json: boolean = false) {
    if (json) {
      return writeTextFile(filePath, JSON.stringify(content, null, 2))
    }
    return writeTextFile(filePath, content)
  }

  private async read(filePath: string, json: boolean = false) {
    let content = null
    try {
      if (await exists(filePath)) {
        content = await readTextFile(filePath)

        if (json) {
          content = JSON.parse(content as string)
        }
      }
    } catch (error) {
      this.logger.error(error)
    }
    return content
  }
}
