package processor

import (
	"errors"
	"io"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"time"
)

// Функция copyFile находит файл в репозитории и создает его копию.
func copyFiles(path string, filename []string) (filenameCopied []string, err error) {
	for i := 0; i < len(filename); i++ {
		input, err := os.Open(path + filename[i])
		if err != nil {
			log.Println("Ошибка открытия input файла: ", err)
		}
		defer func() {
			err = input.Close()
			if err != nil {
				log.Println("Ошибка закрытия input файла.")
			}
		}()

		output, err := os.Create(time.Now().Format("15-04-05") + "video.mkv")
		if err != nil {
			log.Println("Ошибка создания output файла: ", err)
		}
		defer func() {
			err = output.Close()
			if err != nil {
				log.Println("Ошибка закрытия output файла.")
			}

		}()

		_, err = io.Copy(output, input)
		if err != nil {
			log.Println("Ошибка копирования файла")
		}
	}

	log.Println("Файлы скопированы.")
	return filename, err
}

// MergeMKV принимает названия видеофайлов для объединения.
func MergeMKV(filenames ...string) {
	// Создание файла со списком видеофайлов для объединения
	f, err := os.Create("videoList.txt")
	if err != nil {
		log.Fatalln("Ошибка создания файла со списком видеофайлов для объединения", err)
	}
	defer func() {
		err = f.Close()
		if err != nil {
			log.Fatalln("Ошибка закрытия файла: ", err.Error())
		}
	}()

	// Запись видеофайлов для объединения
	n := len(filenames)

	for i := 0; i < n; i++ {
		_, err = f.WriteString("file '" + filenames[i] + "'\n")
		if err != nil {
			log.Fatalln(err)
		}
	}

	err = mergeFfmpeg(f)
	if err != nil {
		log.Fatalln("Ошибка объединения видеофайлов с помощью ffmpeg: ", err)
	}

	err = os.Remove("videoList.txt")
	if err != nil {
		log.Println("Ошибка удаления временного файла videoList.txt: ", err)
	}
	log.Println("Временный файл videoList.txt успешно удален")
}

// DeleteTrimmedFragments удаляет временно созданные файлы.
func DeleteTrimmedFragments(filenames ...string) {
	n := len(filenames)

	for i := 0; i < n; i++ {
		err := os.Remove(filenames[i])
		if err != nil {
			log.Printf("Ошибка удаления временного файла %s: %s", filenames[i], err.Error())
		}
		log.Printf("Временный файл %s успешно удален", filenames[i])
	}
}

// Конвертация времени из формата строки в формат чисел
func partitionTime(time string) (startHour int, startMinute int, err error) {
	// Разделение часов и минут
	s := []byte(time)
	h := []byte{s[0], s[1]}
	m := []byte{s[3], s[4]}

	// Преобразование часов и минут в целые числа
	startHour, err = strconv.Atoi(string(h))
	if err != nil {
		return 0, 0, err
	}
	startMinute, err = strconv.Atoi(string(m))
	if err != nil {
		return 0, 0, err
	}

	return startHour, startMinute, nil
}

// Формирование имени файла
func createFilename(time, date string) (fileName string) {
	s := []byte(time)
	s[3], s[4] = '0', '0'
	fileName = string(s) + "_" + date + ".mkv"
	return fileName
}

// Добавление одного часа к строке в формате ЧЧ-ММ
func addHour(startTime string) (fileName string) {
	s := []byte(startTime)
	if s[0] == '0' && s[1] == '9' {
		s[0] = '1'
		s[1] = '0'
	} else if s[0] == '1' && s[1] == '9' {
		s[0] = '2'
		s[1] = '0'
	} else {
		s[1]++
	}
	fileName = string(s)
	return fileName
}

// Проверка наличия файла
func checkFile(path, fileName string) error {
	found := false

	err := filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error {
		if err != nil {
			return err // Возвращаем ошибку, если возникла
		}
		if !info.IsDir() && info.Name() == fileName {
			log.Println("Файл обнаружен:", filePath)
			found = true
			return filepath.SkipDir // Останавливаем обход после нахождения
		}
		return nil
	})

	if err != nil {
		return err
	}

	if !found {
		return errors.New("file not found")
	}

	return nil
}

// CreateFile проверяет запрошенное количество часов записи, проверяет существование видеофайла в репозитории,
// отрезает запрашиваемый отрезок файла, возвращает обработанный час записи и название обрезанного файла.
//
// При значении параметра durationHour > 0, в первом вызове функции необходимо вручную выставить durationHour на 0.
func CreateFile(startTime, date, path string, startMinute, endMinute, durationHour int) (
	startTimeCreatedFile string, outputFile string) {
	var startM, finishM string

	// Проверка длительности видео
	if endMinute == 60 || endMinute == 0 {
		finishM = "01:00:00"
	} else {
		finishM = "00:" + strconv.Itoa(endMinute) + ":00"
	}

	// Проверка запрошенного количества часов записи
	if durationHour > 0 {
		startTime = addHour(startTime)
		startM = "00:00:00"
	} else {
		startM = "00:" + strconv.Itoa(startMinute) + ":00"
	}

	// Проверка существования видеофайла в репозитории
	filename := createFilename(startTime, date)

	err := checkFile(path, filename)
	if err != nil {
		log.Fatalln("Ошибка начального файла: ", err)
	}

	// Обрезание видеофайла
	inputFile := path + filename

	if endMinute == 60 {

	}

	outputFile = trimMKV(
		inputFile,
		filename,
		startM,
		finishM,
	)

	return startTime, outputFile
}