package main

import (
	"flag"
	"fmt"
	"io/fs"
	"os"
	"strconv"

	"github.com/fatih/color"
)

func usage() {
	//TODO: Fill this out
	fmt.Fprintf(os.Stderr, "Usage:\n")
	os.Exit(1)
}

func check(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err)
		//panic(err) //not sure about this :/
	}
}

func GetFileSize(fi fs.FileInfo) (size string) {
	switch fileSizeFloat := float64(fi.Size()); {
	case fileSizeFloat > (1024 * 1024 * 1024): //GB
		fileSizeFloat /= (1024 * 1024 * 1024)
		size = strconv.FormatFloat(fileSizeFloat, 'f', 1, 64)
		return size + "G"

	case fileSizeFloat > (1024 * 1024): //MB
		fileSizeFloat /= (1024 * 1024)
		size = strconv.FormatFloat(fileSizeFloat, 'f', 1, 64)
		return size + "M"

	case fileSizeFloat > 1024: //KB
		fileSizeFloat /= 1024
		size = strconv.FormatFloat(fileSizeFloat, 'f', 1, 64)
		return size + "K"

	case fileSizeFloat > 0: //B
		size = strconv.FormatFloat(fileSizeFloat, 'f', 0, 64)
		return size

	default:
		return "0"
	}
}

func GetFileModTime(fi fs.FileInfo) (mod string) {
	//day month short time HH:MM
	day := strconv.Itoa(fi.ModTime().Day())
	month := fi.ModTime().Month().String()
	timeH := strconv.Itoa(fi.ModTime().Hour())
	timeM := strconv.Itoa(fi.ModTime().Minute())

	if len(day) == 1 {
		day = " " + day
	}

	if len(timeH) <= 1 {
		timeH = "0" + timeH
	}
	if len(timeM) <= 1 {
		timeM = "0" + timeM
	}

	mod = day + " " + month[0:3] + " " + timeH + ":" + timeM
	return mod
}

func GetFileType() {
	//TODO: this function returns the dxrxrx stuff!
}

func PrintHeaders() {
	headersOutput := color.New(color.FgHiBlack).Add(color.Underline)
	headersOutput.Printf("%-10s ", "Type")
	headersOutput.Printf("%7s ", "Size")
	headersOutput.Printf("%5s ", "Time")
	headersOutput.Printf("%11s\n", "Name")
}
func PrintWithoutL(content []fs.DirEntry, isFlagAEnable *bool) {
	dirOutput := color.New(color.FgMagenta, color.Bold)
	fileOutput := color.New(color.FgWhite, color.Bold)
	for _, item := range content {
		//check if the item is a hidden item (starts with . )
		if item.Name()[:1] == "." && !*isFlagAEnable {
			continue //skip the file
		}
		//check if item is dir
		if item.IsDir() {
			dirOutput.Printf(" %s ", item.Name())
		} else {
			fileOutput.Printf(" %s ", item.Name())
		}

	}
	fmt.Println()
}

func PrintWithL(content []fs.DirEntry, isFlagAEnable *bool) {
	dirOutput := color.New(color.FgMagenta, color.Bold)
	fileOutput := color.New(color.FgWhite, color.Bold)

	//print headers
	PrintHeaders()
	for _, item := range content {
		//we now need extra info from the files
		fi, err := os.Stat(item.Name())
		check(err)

		fType := item.Type().String()
		fDirSize := "-"
		fSize := GetFileSize(fi)
		fModTime := GetFileModTime(fi)

		//check if the item is a hidden item (starts with . )
		if item.Name()[:1] == "." && !*isFlagAEnable {
			continue //skip the file
		}
		//check if item is dir
		if item.IsDir() {
			dirOutput.Printf("%s %7s %7s\t%s\n", fType, fDirSize, fModTime, item.Name()) //leave this
		} else {
			fmt.Printf("%7s %7s %4s", fType, fSize, fModTime)
			fileOutput.Printf("\t%s\n", item.Name())
		}

	}
	fmt.Println()
}

func main() {
	var flagNoColor = flag.Bool("no-colour", false, "Disable color output")
	var flagEnableL = flag.Bool("l", false, "Enable ls -l output")
	var flagEnableA = flag.Bool("a", false, "Enable ls -a output")

func main() {
	var flagNoColor = flag.Bool("no-colour", false, "Disable color output")
	var flagNoList = flag.Bool("no-l", false, "Disable ls -l output")
	var dir string

	flag.Parse()

	if *flagNoColor {
		color.NoColor = true
	}

	//check if we can read the directory
	pwd := os.Getenv("PWD")
	content, err := os.ReadDir(pwd)
	check(err)
	if !*flagEnableL {
		PrintWithoutL(content, flagEnableA)
	} else {
		PrintWithL(content, flagEnableA)
	dirOutput := color.New(color.FgCyan, color.Bold)
	fileOutput := color.New(color.FgWhite, color.Bold)

	}
}
