using System;
using System.Collections.Generic;
using Unity.VisualScripting.FullSerializer;

public enum ReferencePointLocation
{
    Near, Far, RightTop, RightBottom, LeftTop, LeftBottom
}
public enum FlickDirection
{
    Up, RightUp, Right, RightDown, Down, LeftDown, Left, LeftUp, Any
}

/// <summary>
/// 用于创建持久化数据的类
/// </summary>
[Serializable]
public class Chart
{
    public string version { get; set; }
    public META META { get; set; }
    public GlobalConfig globalConfig { get; set; }
    public List<BPMListItem> BPMList { get; set; }
    public List<NoteListItem> noteList { get; set; }
    public List<DragListItem> dragList { get; set; }
    public List<DataFlowListItem> dataFlowList { get; set; }
    public List<FlickListItem> flickList { get; set; }
    public List<LandMineListItem> landMineList { get; set; }
    public Chart()
    {
        BPMList = new List<BPMListItem>();
        noteList = new List<NoteListItem>();
        dragList = new List<DragListItem>();
        dataFlowList = new List<DataFlowListItem>();
        flickList = new List<FlickListItem>();
        landMineList = new List<LandMineListItem>();
        globalConfig = new GlobalConfig();  
        META = new META();
    }
    public override string ToString()
    {
        return $"Chart: version={version}, \n" +
               $"META=[{META}], \n" +
               $"globalConfig=[{globalConfig}], \n" +
               $"BPMList={BPMList?.Count ?? 0} items, \n" +
               $"noteList={noteList?.Count ?? 0} items, \n" +
               $"dragList={dragList?.Count ?? 0} items, \n" +
               $"dataFlowList={dataFlowList?.Count ?? 0} items, \n" +
               $"flickList={flickList?.Count ?? 0} items, \n" +
               $"landMineList={landMineList?.Count ?? 0} items, \n";
              
    }
}

[Serializable]
public class META
{
    public string songName { get; set; }
    public string songWriter { get; set; }
    public string chartDesigner { get; set; }
    public string illustrator { get; set; }
    public override string ToString()
    {
        return $"META(songName={(songName)}, " +
               $"songWriter={(songWriter)}, " +
               $"chartDesigner={(chartDesigner)}, " +
               $"illustrator={(illustrator)})";
    }
}
public class GlobalConfig
{
    public float baseBPM { get; set; }
    public float baseSpeed { get; set; } = 25;
    public float trackLength { get; set; } = 125;
    public float noteStream { get; set; }
    public float BPM { get; set; }
    public override string ToString()
    {
        return $"GlobalConfig(" +
               $"baseBPM={baseBPM}, " +
               $"baseSpeed={baseSpeed}, " +
               $"trackLength={trackLength}, " +
               $"noteStream={noteStream}, " +
               $"BPM={BPM})";
    }
}


[Serializable]
public class BPMListItem
{
    public BPMListItem() { }
    public BPMListItem(float bpm, float startTime, int number)
    {
        this.bpm = bpm;
        this.startTime = startTime;
        this.number = number;
    }

    public float bpm { get; set; }
    public float startTime { get; set; }
    public int number { get; set; }
}

[Serializable]
public class NoteListItem 
{
    public NoteListItem() { }
    public NoteListItem(float x, float y, float targetTime, int timingGroup)
    {
        this.x = x;
        this.y = y;
        this.targetTime = targetTime;
        this.timingGroup = timingGroup;
    }

    public float x { get; set; }
    public float y { get; set; }
    public float targetTime { get; set; }
    public int timingGroup { get; set; }
}

[Serializable]
public class DragListItem 
{
    public DragListItem() { }
    public DragListItem(float x, float y, float targetTime, int timingGroup)
    {
        this.x = x;
        this.y = y;
        this.targetTime = targetTime;
        this.timingGroup = timingGroup;
    }

    public float x { get; set; }
    public float y { get; set; }
    public float targetTime { get; set; }
    public int timingGroup { get; set; }
}

[Serializable]
public class FlickListItem 
{
    public FlickListItem() { }
    public FlickListItem(float x, float y, float targetTime,int timingGroup, FlickDirection direction)
    {
        this.x = x;
        this.y = y;
        this.targetTime = targetTime;
        this.timingGroup = timingGroup;
        this.direction = direction;
    }

    public float x { get; set; }
    public float y { get; set; }
    public float targetTime { get; set; }
    public int timingGroup { get; set; }
    public FlickDirection direction { get; set; }
}

[Serializable]
public class LandMineListItem 
{
    public LandMineListItem() { }
    public LandMineListItem(float x, float y, float startTime, float endTime)
    {
        this.x = x;
        this.y = y;
        this.startTime = startTime;
        this.endTime = endTime;
    }

    public float x { get; set; }
    public float y { get; set; }
    public float startTime { get; set; }
    public float endTime { get; set; }
}

[Serializable]
public class DataFlowListItem
{ 
    public DataFlowListItem() { }
    public DataFlowListItem(float startX, float startY, float endX, float endY,
                           float startTime, float endTime, bool isTriggers,
                           int timingGroup, ReferencePointLocation type)
    {
        this.startX = startX;
        this.startY = startY;
        this.endX = endX;
        this.endY = endY;
        this.startTime = startTime;
        this.endTime = endTime;
        this.isTriggers = isTriggers;
        this.timingGroup = timingGroup;
        this.type = type;
    }

    public float startX { get; set; }
    public float startY { get; set; }
    public float endX { get; set; }
    public float endY { get; set; }
    public float startTime { get; set; }
    public float endTime { get; set; }
    public bool isTriggers { get; set; }
    public int timingGroup { get; set; }
    public ReferencePointLocation type { get; set; }
}

// 新增：特效系统
[Serializable]
public class EffectData
{
    public EffectData() { }
    public EffectData(string effectId, float startTime, float duration, Dictionary<string, object> parameters)
    {
        this.effectId = effectId;
        this.startTime = startTime;
        this.duration = duration;
        this.parameters = parameters;
    }

    public string effectId;
    public float startTime;
    public float duration;
    public Dictionary<string, object> parameters;
}


