package utils

import (
	"encoding/base64"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"pbx-api-gin/pkg/lfshook"
	"strconv"
	"strings"
)

// FileExists checks if a file exists and is not a directory before we
// try using it to prevent further errors.
func FileExists(filename string) bool {
	info, err := os.Stat(filename)
	if os.IsNotExist(err) {
		return false
	}
	return !info.IsDir()
}

func GetDuration(filePath string) (int, error) {
	cmd := exec.Command("ffprobe",
		"-v", "quiet",
		"-show_entries", "format=duration",
		"-of", "default=nw=1:nokey=1",
		filePath,
	)

	output, err := cmd.Output()
	if err != nil {
		lfshook.NewLogger().Logger.Infof("=======GetDuration err:%+v ! ============", output)
		return 0, err
	}

	// 解析输出（纯数字，单位秒）
	durationStr := strings.TrimSpace(string(output))
	duration, err := strconv.ParseFloat(durationStr, 64)
	if err != nil {
		return 0, err
	}

	return int(duration), nil
}

func AudioFileEncode(dstFile, srcFile string) error {
	// Step 1:获取 Base64 编码结果
	data := "sripis123"
	encoded := base64.StdEncoding.EncodeToString([]byte(data))

	// Step 2: 创建一个新文件，写入 Base64 编码结果
	outputFile, err := os.Create(dstFile)
	if err != nil {
		return err
	}
	defer outputFile.Close()

	_, err = outputFile.WriteString(encoded)
	if err != nil {
		return err
	}

	// Step 3: 打开 audio.wav 文件
	audioFile, err := os.Open(srcFile)
	if err != nil {
		return err
	}
	defer audioFile.Close()

	// Step 4: 读取源文件的全部内容
	data1, err := io.ReadAll(audioFile)
	if err != nil {
		return err
	}

	// Step 5: 对读取的内容进行 Base64 编码
	encoded1 := base64.StdEncoding.EncodeToString(data1)

	// Step 6: 写入 Base64 编码后的内容
	_, err = outputFile.WriteString(encoded1)
	if err != nil {
		return err
	}
	return err
}

// ConvertAndSegmentWAV 将 WAV 文件转为 22kHz 并每 180 秒切分，返回生成的文件名列表
func ConvertAndSegmentWAV(inputFile string, outputPrefix string) ([]string, error) {
	// 输出文件命名模式，如：output_%03d.wav
	outputPattern := outputPrefix + "_%03d.wav"

	// 构建 ffmpeg 命令
	cmd := exec.Command("ffmpeg",
		"-i", inputFile, // 输入文件
		"-ar", "22050", // 设置采样率为 22050 Hz (22kHz)
		"-f", "segment", // 启用分段模式
		"-segment_time", "180", // 每段 180 秒
		"-c:a", "pcm_s16le", // 音频编码格式（标准 WAV）
		"-reset_timestamps", "1", // 重置时间戳，每个片段从 0 开始
		outputPattern, // 输出文件命名规则
	)

	// 执行命令并捕获输出
	output, err := cmd.CombinedOutput()
	if err != nil && !strings.Contains(string(output), "Conversion failed!") {
		// 即使有警告（如非关键错误），只要文件生成了就继续解析
		//log.Printf("ffmpeg 执行时有警告: %v", err)
		lfshook.NewLogger().Logger.Infof("=======ConvertAndSegmentWAV err:%+v ! ============", output)
	}
	// 解析输出，提取所有生成的文件名
	files := extractFilenamesFromFFmpegOutput(outputPrefix)

	//lfshook.NewLogger().Infof("found after convert outfiles %+v ", files)
	return files, nil
}

// extractFilenamesFromFFmpegOutput 从 ffmpeg 输出日志中提取生成的文件名
func extractFilenamesFromFFmpegOutput(prefix string) []string {
	pattern := fmt.Sprintf("%s_*", prefix)
	matches, err := filepath.Glob(pattern)
	if err != nil {
		//log.Fatal("模式匹配错误:", err)
		lfshook.NewLogger().Logger.Infof("=======模式匹配错误:%+v ! ============", err)
	}

	return matches
}

var Logger *log.Logger
var LoggerDebug *log.Logger

func init() {
	file, _ := os.OpenFile("/data/test/log/recordEvent.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	//Logger = log.New(file, "", log.LstdFlags) // 自动带时间戳
	Logger = log.New(file, "", log.LstdFlags|log.Lmicroseconds)
	//lfshook.NewLogger().Printf("software version: V10.01")

	fileDebug, _ := os.OpenFile("/data/test/log/debug.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	//Logger = log.New(file, "", log.LstdFlags) // 自动带时间戳
	LoggerDebug = log.New(fileDebug, "", log.LstdFlags|log.Lmicroseconds|log.Llongfile)
}

func GetPadInfo(base string) (padType, padNum, connectedCab string) {
	// 按 '/' 分割字符串
	parts := strings.Split(base, "/")

	// 取最后一段
	lastPart := parts[len(parts)-1]
	// 最后一段中，按‘-’分割返回前三段：parts[0], parts[1], parts[2] → PAD-2411-1411
	ret := strings.Split(lastPart, "-")
	if len(ret) < 3 {
		return
	}
	return ret[0], ret[1], ret[2]
}
