// Package preflight prüft vor dem Supervise-Flow:
//   - iPhone via USB erreichbar (über device.Connect)
//   - ProductType iPhone/iPad (kein Mac, kein Apple-TV)
//   - iOS-Version >= 16
//   - ActivationState=Activated
//   - Find-My-iPhone aus (via NonVolatileRAM-Parse)
//   - IsSupervised-Status anzeigen (kein Hard-Fail bei true — caller entscheidet)
package preflight

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/raynis/rebreak-supervise-magic/internal/device"
)

type Result struct {
	OK      bool
	Reasons []string
	Device  DeviceInfo
}

type DeviceInfo struct {
	UDID            string
	DeviceName      string
	ProductType     string
	ProductVersion  string
	ActivationState string
	FindMyEnabled   bool
	IsSupervised    bool
}

func Run(conn *device.Conn) (*Result, error) {
	res := &Result{OK: true}

	info, err := conn.Info()
	if err != nil {
		return nil, fmt.Errorf("preflight: device info: %w", err)
	}

	res.Device.UDID = conn.UDID()
	res.Device.DeviceName = asString(info["DeviceName"])
	res.Device.ProductType = asString(info["ProductType"])
	res.Device.ProductVersion = asString(info["ProductVersion"])
	res.Device.ActivationState = asString(info["ActivationState"])

	if supervised, err := conn.IsSupervised(); err == nil {
		res.Device.IsSupervised = supervised
	}
	if fmi, err := conn.FindMyEnabled(); err == nil {
		res.Device.FindMyEnabled = fmi
	}

	if res.Device.FindMyEnabled {
		res.OK = false
		res.Reasons = append(res.Reasons,
			"Find My iPhone is ON — disable in Settings → [Name] → Wo ist? → Mein iPhone suchen → AUS")
	}

	if !strings.HasPrefix(res.Device.ProductType, "iPhone") && !strings.HasPrefix(res.Device.ProductType, "iPad") {
		res.OK = false
		res.Reasons = append(res.Reasons,
			fmt.Sprintf("ProductType '%s' not supported — only iPhone/iPad. Mac uses different stack (NanoMDM enrollment).", res.Device.ProductType))
	}

	if !checkIOSVersionAtLeast(res.Device.ProductVersion, 16) {
		res.OK = false
		res.Reasons = append(res.Reasons,
			fmt.Sprintf("OS-Version '%s' too low. Need iOS 16+ for Cloud-Config-Plist-Path.", res.Device.ProductVersion))
	}

	if res.Device.ActivationState != "" && res.Device.ActivationState != "Activated" {
		res.OK = false
		res.Reasons = append(res.Reasons,
			fmt.Sprintf("ActivationState '%s' — device must be activated.", res.Device.ActivationState))
	}

	if len(res.Reasons) > 0 {
		res.OK = false
	}
	return res, nil
}

func asString(v any) string {
	if s, ok := v.(string); ok {
		return s
	}
	return ""
}

func checkIOSVersionAtLeast(version string, minMajor int) bool {
	if version == "" {
		return true
	}
	parts := strings.SplitN(version, ".", 2)
	if len(parts) == 0 {
		return true
	}
	major, err := strconv.Atoi(parts[0])
	if err != nil {
		return true
	}
	return major >= minMajor
}
