using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using ZXing;

public class ImageTracker : MonoBehaviour
{
    ARCameraManager cameraManager;

    [SerializeField] List<string> listName;
    [SerializeField] List<GameObject> listAnimal;
    [SerializeField] float spawnScale = 0.3f;
    [SerializeField] float spawnDistance = 1.5f;

    Dictionary<string, GameObject> dictPrefab = new();
    Dictionary<string, GameObject> dictSpawn = new();

    // 현재 소환된 QR 이름 추적
    string currentName = "";

    IBarcodeReader reader = new BarcodeReader();

    void Awake()
    {
        cameraManager = FindFirstObjectByType<ARCameraManager>();

        for (int i = 0; i < listName.Count; i++)
            dictPrefab[listName[i]] = listAnimal[i];
    }

    void OnEnable() => StartCoroutine(ScanQR());
    void OnDisable() => StopAllCoroutines();

    IEnumerator ScanQR()
    {
        while (true)
        {
            yield return new WaitForSeconds(0.5f);

            if (!cameraManager.TryAcquireLatestCpuImage(out var cpuImage)) continue;

            using (cpuImage)
            {
                var tex = new Texture2D(cpuImage.width, cpuImage.height, TextureFormat.RGBA32, false);
                var conversionParams = new XRCpuImage.ConversionParams(cpuImage, TextureFormat.RGBA32);
                var buffer = tex.GetRawTextureData<byte>();
                cpuImage.Convert(conversionParams, buffer);
                tex.Apply();

                var result = reader.Decode(tex.GetPixels32(), tex.width, tex.height);
                Destroy(tex);

                if (result == null) continue;
                if (!dictPrefab.ContainsKey(result.Text)) continue;

                string detected = result.Text;

                // 같은 QR이면 무시
                if (detected == currentName) continue;

                SpawnCharacter(detected);
            }
        }
    }

    void SpawnCharacter(string name)
    {
        // 이전 동물 전부 Destroy
        foreach (var key in new List<string>(dictSpawn.Keys))
            DestroyCharacter(key);

        Vector3 spawnPos = GetSpawnPosition();
        var go = Instantiate(dictPrefab[name], spawnPos, Quaternion.identity);
        go.transform.localScale = Vector3.one * spawnScale;

        // 카메라를 바라보도록 회전
        Vector3 lookDir = Camera.main.transform.position - spawnPos;
        lookDir.y = 0;
        go.transform.rotation = Quaternion.LookRotation(lookDir);

        dictSpawn[name] = go;
        currentName = name;
    }

    void DestroyCharacter(string name)
    {
        if (!dictSpawn.ContainsKey(name)) return;
        Destroy(dictSpawn[name]);
        dictSpawn.Remove(name);
    }

    Vector3 GetSpawnPosition()
    {
        Transform cam = Camera.main.transform;
        return cam.position + cam.forward * spawnDistance;
    }
}