using System;
using UnityEditor;
using UnityEngine;

namespace AvatarRefinery.Editor.Core
{
    /// <summary>
    /// 修正機能(製品版パッケージ com.avatarrefinery.pro)が Lite の UI に差し込むための拡張点。
    /// Lite 単体では <see cref="Current"/> は null で、UI は「手順の表示+要望フォーム」のまま動く。
    /// 製品版は [InitializeOnLoad] で <see cref="Register"/> を呼び、各フックで IMGUI を描画する。
    /// </summary>
    public abstract class FixHost
    {
        public static FixHost Current { get; private set; }
        public static bool Available => Current != null;

        public static void Register(FixHost host)
        {
            Current = host;
        }

        /// <summary>ツールバー等に表示する製品ラベル(例: "製品版")</summary>
        public abstract string ProductLabel { get; }

        /// <summary>この Issue に実行可能な修正があるか(「修正する」ボタンを出すか)</summary>
        public abstract bool CanFix(FixUiContext ctx, Issue issue);

        /// <summary>サマリ直下(重要度トグルの下)。「まとめて修正」「Before/After」など。</summary>
        public abstract void DrawSummary(FixUiContext ctx);

        /// <summary>各 Issue のアクション行。Lite の「自動修正が欲しい」ボタンの代わりに描画される。</summary>
        public abstract void DrawIssueActions(FixUiContext ctx, Issue issue);

        /// <summary>各 Issue の本文の末尾(プレビュー等、行をまたぐ描画用)。</summary>
        public virtual void DrawIssueBody(FixUiContext ctx, Issue issue) { }

        /// <summary>フッター(「すべて元に戻す」「バックアップ場所」など)。</summary>
        public abstract void DrawFooter(FixUiContext ctx);

        /// <summary>フッターの「読み取り専用」文言の差し替え(null なら Lite の既定文)。</summary>
        public virtual string FooterNote => null;
    }

    /// <summary>フック描画時にウィンドウが渡す状態と操作。</summary>
    public sealed class FixUiContext
    {
        public EditorWindow Window;
        public GameObject Avatar;
        public DiagnosisReport Report;
        /// <summary>直前の診断結果(修正→再診断の Before/After 用。無ければ null)</summary>
        public DiagnosisReport Previous;
        public bool Detailed;
        /// <summary>再診断を実行する(前回のレポートは Previous に保持される)</summary>
        public Action Rediagnose;
        public Action Repaint;
        public Func<Issue, bool> IsIgnored;
        public Func<Issue, string> IssueKey;
    }
}
