using Microsoft.UI;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;
using System.Collections.ObjectModel;
using TornadoAce_CJOnStyle.Domain;
using TornadoAce_CJOnStyle.Services;
using Windows.UI;

namespace TornadoAce_CJOnStyle.ViewModels
{
    public partial class MainViewModel : BaseViewModel
    {
        private readonly AutomationWorkspace workspace;
        private readonly PocAutomationEngine automationEngine;
        private int selectedCueSheetIndex;
        private CueSheetRecord activeCueSheet = null!;
        private SceneDataSnapshot activeScene = null!;

        public MainViewModel()
        {
            Title = "CG 제작 자동화";
            workspace = AutomationWorkspace.CreateDemo();
            automationEngine = new PocAutomationEngine(workspace);
            var initialSelection = automationEngine.SelectCueSheet(selectedCueSheetIndex);
            var initialInspectionSummary = automationEngine.InspectWorkspace(workspace.ActiveTemplate);
            activeCueSheet = initialSelection.Record;
            activeScene = automationEngine.GenerateScene(activeCueSheet, workspace.ActiveTemplate);

            BuildPhase = "INITIAL BUILD";
            OperatorMessage = "큐시트 플랫폼, Tornado Scene 템플릿, 자동 검수 결과를 한 화면에서 확인하는 운영 콘솔 초안입니다.";
            LastCueSheetSyncText = FormatCueSheetSelection(initialSelection);
            ActiveTemplateName = workspace.ActiveTemplate.TemplateName;
            InspectionSummary = FormatInspectionSummary(initialInspectionSummary);
            SceneSnapshotLabel = $"{activeScene.SceneName} / visible text objects";
            SceneSnapshotText = activeScene.ToPreviewJson();
            LoginOperatorName = "producer";
            LaunchMessage = "TornadoAce";
            LlmPolicyText = "사내 LLM 우선, 외부 서비스는 정책 승인 후";
            LlmPolicyDetail = "1차 Text Diffing 실패 건만 2차 LLM 판정으로 이동하고, 가격·구성·방송시간 변경은 높은 중요도로 표시합니다.";

            LoadStatusCards();
            LoadPipelineSteps();
            LoadFieldMappings();
            LoadEndpoints();
            LoadRequirementCoverage();
            LoadInspectionQueue(initialInspectionSummary.Results);
        }

        private string buildPhase = string.Empty;
        private string operatorMessage = string.Empty;
        private string lastCueSheetSyncText = string.Empty;
        private string activeTemplateName = string.Empty;
        private string inspectionSummary = string.Empty;
        private string sceneSnapshotLabel = string.Empty;
        private string sceneSnapshotText = string.Empty;
        private string llmPolicyText = string.Empty;
        private string llmPolicyDetail = string.Empty;
        private string loginOperatorName = string.Empty;
        private string launchMessage = string.Empty;
        private Visibility loginScreenVisibility = Visibility.Visible;
        private Visibility launchScreenVisibility = Visibility.Collapsed;
        private Visibility mainShellVisibility = Visibility.Collapsed;

        public string BuildPhase
        {
            get => buildPhase;
            set => SetProperty(ref buildPhase, value);
        }

        public string OperatorMessage
        {
            get => operatorMessage;
            set => SetProperty(ref operatorMessage, value);
        }

        public string LastCueSheetSyncText
        {
            get => lastCueSheetSyncText;
            set => SetProperty(ref lastCueSheetSyncText, value);
        }

        public string ActiveTemplateName
        {
            get => activeTemplateName;
            set => SetProperty(ref activeTemplateName, value);
        }

        public string InspectionSummary
        {
            get => inspectionSummary;
            set => SetProperty(ref inspectionSummary, value);
        }

        public string SceneSnapshotLabel
        {
            get => sceneSnapshotLabel;
            set => SetProperty(ref sceneSnapshotLabel, value);
        }

        public string SceneSnapshotText
        {
            get => sceneSnapshotText;
            set => SetProperty(ref sceneSnapshotText, value);
        }

        public string LlmPolicyText
        {
            get => llmPolicyText;
            set => SetProperty(ref llmPolicyText, value);
        }

        public string LlmPolicyDetail
        {
            get => llmPolicyDetail;
            set => SetProperty(ref llmPolicyDetail, value);
        }

        public ObservableCollection<StatusCardViewModel> StatusCards { get; } = [];

        public ObservableCollection<PipelineStepViewModel> PipelineSteps { get; } = [];

        public ObservableCollection<FieldMappingViewModel> FieldMappings { get; } = [];

        public ObservableCollection<IntegrationEndpointViewModel> Endpoints { get; } = [];

        public ObservableCollection<PocRequirementViewModel> RequirementCoverage { get; } = [];

        public ObservableCollection<InspectionQueueItemViewModel> InspectionQueue { get; } = [];

        public string LoginOperatorName
        {
            get => loginOperatorName;
            set => SetProperty(ref loginOperatorName, value);
        }

        public string LaunchMessage
        {
            get => launchMessage;
            set => SetProperty(ref launchMessage, value);
        }

        public Visibility LoginScreenVisibility
        {
            get => loginScreenVisibility;
            set => SetProperty(ref loginScreenVisibility, value);
        }

        public Visibility LaunchScreenVisibility
        {
            get => launchScreenVisibility;
            set => SetProperty(ref launchScreenVisibility, value);
        }

        public Visibility MainShellVisibility
        {
            get => mainShellVisibility;
            set => SetProperty(ref mainShellVisibility, value);
        }

        public void BeginLogin(string operatorName, string accessCode)
        {
            LoginOperatorName = string.IsNullOrWhiteSpace(operatorName) ? "producer" : operatorName.Trim();
            LaunchMessage = "TornadoAce";
            LoginScreenVisibility = Visibility.Collapsed;
            LaunchScreenVisibility = Visibility.Visible;
        }

        public void CompleteLogin()
        {
            LaunchScreenVisibility = Visibility.Collapsed;
            MainShellVisibility = Visibility.Visible;
            OperatorMessage = $"{LoginOperatorName} 제작자가 접속했습니다. 큐시트와 Scene 매핑 상태를 확인하세요.";
        }

        [RelayCommand]
        private void RefreshCueSheet()
        {
            selectedCueSheetIndex++;
            var selection = automationEngine.SelectCueSheet(selectedCueSheetIndex);
            activeCueSheet = selection.Record;
            activeScene = automationEngine.GenerateScene(activeCueSheet, workspace.ActiveTemplate);

            LastCueSheetSyncText = FormatCueSheetSelection(selection);
            OperatorMessage = $"{activeCueSheet.ProgramTitle} / {activeCueSheet.ProductName} 큐시트를 선택했습니다.";
            StatusCards[0].Metric = selection.TotalCount.ToString();
            StatusCards[0].Detail = $"선택 {selection.Position}/{selection.TotalCount}";
            ApplySceneSnapshot(activeScene);
        }

        [RelayCommand]
        private void GenerateScene()
        {
            activeScene = automationEngine.GenerateScene(activeCueSheet, workspace.ActiveTemplate);

            OperatorMessage = $"{activeCueSheet.CueSheetId} 데이터를 {activeScene.SceneName} Scene 스냅샷으로 생성했습니다.";
            StatusCards[1].Metric = workspace.ActiveTemplate.Mappings.Count.ToString();
            StatusCards[1].Detail = "필드 매핑 완료";
            ApplySceneSnapshot(activeScene);
        }

        [RelayCommand]
        private void RunInspection()
        {
            var summary = automationEngine.InspectWorkspace(workspace.ActiveTemplate);

            OperatorMessage = "Scene 추출값을 큐시트와 비교했습니다. 가격/구성 불일치는 높은 중요도로 분류합니다.";
            InspectionSummary = FormatInspectionSummary(summary);
            StatusCards[2].Metric = $"{summary.AverageMatchRate:0.0}%";
            StatusCards[2].Detail = $"확인 {summary.ReviewCount}건";
            LoadInspectionQueue(summary.Results);
        }

        private void LoadStatusCards()
        {
            StatusCards.Add(new StatusCardViewModel("큐시트 API", "12", "수신 대기", Symbol.Sync, Brush(0xFF45D6D1)));
            StatusCards.Add(new StatusCardViewModel("Scene 매핑", "5", "템플릿 정의", Symbol.Map, Brush(0xFFB48CFF)));
            StatusCards.Add(new StatusCardViewModel("자동 검수", "98.7%", "목표 99%+", Symbol.Accept, Brush(0xFFFFB547)));
            StatusCards.Add(new StatusCardViewModel("Tornado", "Mock", "SDK 어댑터 자리", Symbol.Repair, Brush(0xFF37D67A)));
        }

        private void LoadPipelineSteps()
        {
            PipelineSteps.Add(new PipelineStepViewModel("01", "큐시트 데이터 수신", "AI ON Studio / 자막 큐시트 API", "설계", 35, Brush(0xFF45D6D1)));
            PipelineSteps.Add(new PipelineStepViewModel("02", "Data Field Mapping", "큐시트 필드 -> Tornado Scene 객체", "초안", 45, Brush(0xFFB48CFF)));
            PipelineSteps.Add(new PipelineStepViewModel("03", "Scene 생성/갱신", "Tornado2 우선, Tornado3 어댑터 준비", "대기", 25, Brush(0xFF37D67A)));
            PipelineSteps.Add(new PipelineStepViewModel("04", "Scene Data API 추출", "Text/Image visible object snapshot", "초안", 30, Brush(0xFFFFB547)));
            PipelineSteps.Add(new PipelineStepViewModel("05", "자동 검수 피드백", "Text Diffing + LLM 중요도 판정", "초안", 40, Brush(0xFFFF5B61)));
        }

        private void LoadFieldMappings()
        {
            foreach (var mapping in workspace.ActiveTemplate.Mappings)
            {
                FieldMappings.Add(new FieldMappingViewModel(mapping.CueSheetField, mapping.SceneObjectName, mapping.Rule, mapping.Attribute));
            }
        }

        private void LoadEndpoints()
        {
            Endpoints.Add(new IntegrationEndpointViewModel("큐시트 플랫폼", "GET /api/cuesheets/{broadcastDate}", "AI ON Studio", "Mock", Brush(0xFF45D6D1)));
            Endpoints.Add(new IntegrationEndpointViewModel("ERP 편성", "GET /api/schedules/{programCode}", "CJ OnStyle ERP", "대기", Brush(0xFFFFB547)));
            Endpoints.Add(new IntegrationEndpointViewModel("Tornado Scene API", "POST /api/scenes/extract", "Tornado Adapter", "설계", Brush(0xFF37D67A)));
            Endpoints.Add(new IntegrationEndpointViewModel("LLM 검수", "POST /api/inspection/llm", "Internal LLM", "정책 확인", Brush(0xFFB48CFF)));
        }

        private void LoadRequirementCoverage()
        {
            RequirementCoverage.Add(new PocRequirementViewModel("RFP-01", "큐시트 API 연동", "PoC", "샘플 큐시트 선택", Brush(0xFF45D6D1)));
            RequirementCoverage.Add(new PocRequirementViewModel("RFP-02", "ERP 편성 연동", "대기", "엔드포인트 자리", Brush(0xFFFFB547)));
            RequirementCoverage.Add(new PocRequirementViewModel("RFP-03", "Data Field Mapping", "PoC", "Scene 스냅샷 생성", Brush(0xFF37D67A)));
            RequirementCoverage.Add(new PocRequirementViewModel("RFP-04", "Tornado Scene API", "PoC", "Text/Image 추출 샘플", Brush(0xFF37D67A)));
            RequirementCoverage.Add(new PocRequirementViewModel("RFP-05", "관리자 매핑 기능", "초안", "매핑표 UI", Brush(0xFFB48CFF)));
            RequirementCoverage.Add(new PocRequirementViewModel("RFP-06", "1·2단계 자동 검수", "PoC", "Diff + LLM 후보", Brush(0xFF45D6D1)));
        }

        private void LoadInspectionQueue(IEnumerable<InspectionResult> results)
        {
            InspectionQueue.Clear();

            foreach (var item in results)
            {
                InspectionQueue.Add(new InspectionQueueItemViewModel(
                    item.ProgramTitle,
                    item.SceneName,
                    $"{item.MatchRate:0.0}%",
                    item.Severity,
                    item.Decision,
                    SeverityBrush(item.Severity)));
            }
        }

        private void ApplySceneSnapshot(SceneDataSnapshot scene)
        {
            SceneSnapshotLabel = $"{scene.SceneName} / {scene.VisibleTextObjects.Count} text objects";
            SceneSnapshotText = scene.ToPreviewJson();
        }

        private static string FormatCueSheetSelection(CueSheetSelection selection)
        {
            return $"목 데이터 {selection.Position}/{selection.TotalCount} · {selection.Record.BroadcastTime:HH:mm}";
        }

        private static string FormatInspectionSummary(PocInspectionSummary summary)
        {
            return $"통과 {summary.PassedCount}건 / 확인 {summary.ReviewCount}건 / 평균 {summary.AverageMatchRate:0.0}%";
        }

        private static SolidColorBrush SeverityBrush(string severity)
        {
            return severity switch
            {
                "High" => Brush(0xFFFF5B61),
                "Medium" => Brush(0xFFFFB547),
                _ => Brush(0xFF37D67A)
            };
        }

        private static SolidColorBrush Brush(uint argb)
        {
            return new SolidColorBrush(Color.FromArgb(
                (byte)(argb >> 24),
                (byte)(argb >> 16),
                (byte)(argb >> 8),
                (byte)argb));
        }
    }
}
