using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Serialization;

[RequireComponent(typeof(MeshRenderer)), RequireComponent(typeof(MeshFilter))]
public class GrassChunk : MonoBehaviour {
    [SerializeField] private Material _materialLOD0;
    public Material MaterialLOD0 {
        get { return _materialLOD0; }
        set {
            _materialLOD0 = value;
            UpdateLODAssets();
        }
    }

    [SerializeField] private Mesh _meshLOD0;
    public Mesh MeshLOD0 {
        get { return _meshLOD0; }
        set {
            _meshLOD0 = value;
            UpdateLODAssets();
        }
    }

    [SerializeField] private bool _enableShadowsLOD0;
    public bool EnableShadowsLOD0 {
        get { return _enableShadowsLOD0; }
        set {
            _enableShadowsLOD0 = value;
            UpdateLODAssets();
        }
    }

    [SerializeField] private Material _materialLOD1;
    public Material MaterialLOD1 {
        get { return _materialLOD1; }
        set {
            _materialLOD1 = value;
            UpdateLODAssets();
        }
    }

    [SerializeField] private Mesh _meshLOD1;
    public Mesh MeshLOD1 {
        get { return _meshLOD1; }
        set {
            _meshLOD1 = value;
            UpdateLODAssets();
        }
    }

    [SerializeField] private bool _enableShadowsLOD1;
    public bool EnableShadowsLOD1 {
        get { return _enableShadowsLOD1; }
        set {
            _enableShadowsLOD1 = value;
            UpdateLODAssets();
        }
    }

    [SerializeField] private Material _materialLOD2;
    public Material MaterialLOD2 {
        get { return _materialLOD2; }
        set {
            _materialLOD2 = value;
            UpdateLODAssets();
        }
    }

    [SerializeField] private Mesh _meshLOD2;
    public Mesh MeshLOD2 {
        get { return _meshLOD2; }
        set {
            _meshLOD2 = value;
            UpdateLODAssets();
        }
    }

    [SerializeField] private bool _enableShadowsLOD2;
    public bool EnableShadowsLOD2 {
        get { return _enableShadowsLOD2; }
        set {
            _enableShadowsLOD2 = value;
            UpdateLODAssets();
        }
    }

    private int _lod;
    public int LOD {
        get { return _lod; }
        set {
            if (_lod == value) return;

            _lod = value;
            UpdateLODAssets();
        }
    }

    private MeshRenderer _meshRenderer;
    public MeshRenderer MeshRenderer {
        get {
            if (!_meshRenderer) {
                _meshRenderer = GetComponent<MeshRenderer>();
            }
            return _meshRenderer;
        }
        private set { _meshRenderer = value; }
    }

    private MeshFilter _meshFilter;
    public MeshFilter MeshFilter {
        get {
            if (!_meshFilter) {
                _meshFilter = GetComponent<MeshFilter>();
            }
            return _meshFilter;
        }
        private set { _meshFilter = value; }
    }

    private void UpdateLODAssets() {
        switch (_lod) {
            case 0:
                MeshRenderer.sharedMaterial = _materialLOD0;
                MeshRenderer.shadowCastingMode = EnableShadowsLOD0 ? ShadowCastingMode.On : ShadowCastingMode.Off;
                MeshFilter.sharedMesh = _meshLOD0;
                break;
            case 1:
                MeshRenderer.sharedMaterial = _materialLOD1;
                MeshRenderer.shadowCastingMode = EnableShadowsLOD1 ? ShadowCastingMode.On : ShadowCastingMode.Off;
                MeshFilter.sharedMesh = _meshLOD1;
                break;
            case 2:
                MeshRenderer.sharedMaterial = _materialLOD2;
                MeshRenderer.shadowCastingMode = EnableShadowsLOD2 ? ShadowCastingMode.On : ShadowCastingMode.Off;
                MeshFilter.sharedMesh = _meshLOD2;
                break;
        }
    }

    private void OnDrawGizmos() {
        Gizmos.color = new Color(1f, 0.7f, 0f, 0.5f);
        var meshRenderer = GetComponent<MeshRenderer>();
        var bounds = meshRenderer.bounds;
        Gizmos.DrawWireCube(bounds.center, bounds.size);
    }
}
