﻿using System;
using JLGames.RocketDriver.CSharp;
using JLGames.RocketDriver.Games.RpgMaterial.User;
using UnityEngine;

namespace JLGames.RocketDriver.Games.RpgMaterial.Asset
{
    [Serializable]
    public class MaterialAssetData : ICloneable<MaterialAssetData>, ICloneable
    {
        [Tooltip("Material Id\n材料Id")] public int MId;
        [Tooltip("Material num\n材料数量")] public int Num;
        [Tooltip("Material unique id\n材料独立Id")] public int UId;

        public override string ToString()
        {
            return $"{{MId={MId}, UId={UId}, Num={Num}}}";
        }

        public MaterialAssetData Clone()
        {
            return new MaterialAssetData {MId = MId, UId = UId, Num = Num};
        }

        object ICloneable.Clone()
        {
            return Clone();
        }

        public static TU ToUserMaterial<TD, TU>(TD d, int type)
            where TD : MaterialAssetData
            where TU : IUserMaterialMod, new()
        {
            var rs = new TU();
            rs.SetType(type);
            rs.SetMId(d.MId);
            rs.SetUId(d.UId);
            rs.SetNum(d.Num);
            return rs;
        }

        public static TU[] ToUserMaterials<TD, TU>(TD[] d, int type)
            where TD : MaterialAssetData
            where TU : IUserMaterialMod, new()
        {
            return ToUserMaterials<TD, TU, TU>(d, type);
        }

        public static ITU[] ToUserMaterials<TD, ITU, TU>(TD[] d, int type)
            where TD : MaterialAssetData
            where TU : IUserMaterialMod, ITU, new()
        {
            if (null == d) return null;
            if (d.Length == 0) return new ITU[0];
            var rs = new ITU[d.Length];
            for (var index = 0; index < d.Length; index++)
            {
                rs[index] = ToUserMaterial<TD, TU>(d[index], type);
            }

            return rs;
        }

        public static TD FromUserMaterial<TD, TU>(TU u)
            where TD : MaterialAssetData, new()
            where TU : IUserMaterial
        {
            var rs = new TD()
            {
                MId = u.MId,
                UId = u.UId,
                Num = u.Num
            };
            return rs;
        }

        public static TD[] FromUserMaterials<TD, TU>(TU[] us)
            where TD : MaterialAssetData, new()
            where TU : IUserMaterial
        {
            return FromUserMaterials<TD, TD, TU>(us);
        }

        public static ITD[] FromUserMaterials<ITD, TD, TU>(TU[] us)
            where TD : MaterialAssetData, ITD, new()
            where TU : IUserMaterial
        {
            if (null == us) return null;
            if (us.Length == 0) return new ITD[0];
            var rs = new ITD[us.Length];
            for (var index = 0; index < us.Length; index++)
            {
                rs[index] = FromUserMaterial<TD, TU>(us[index]);
            }

            return rs;
        }
    }
}