using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.Text.Json;
using System.Net.Http.Json;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using Front.Program.Layout;
using Front.Program.Services;

namespace Front.Program.Views.Project.ConnectUser;

public partial class Register : ComponentBase
{
    [Inject] IJSRuntime JS { get; set; }
    [Inject] private NavigationManager NavigationManager { get; set; } = default!;
    [Inject] private HttpClient Http { get; set; } = default!;
    [Inject] private IConfiguration Configuration { get; set; } = default!;
    [Inject] private LoadingService LoadingService { get; set; } = default!;
    [Inject] private StorageService CookieService { get; set; } = default!;

    private ElementReference dateInputRef;

    private string name = "";
    private string birthYear = "";
    private string birthMonth = "";
    private string birthDay = "";
    private DateTime? birth;
    private string email = "";
    private string phone = "";
    private string address = "";
    private string detailAddress = "";
    private string snsId = "";

    private string phonePart1 = "";
    private string phonePart2 = "";
    private string phonePart3 = "";

    protected override async Task OnInitializedAsync()
    {
        objRef = DotNetObjectReference.Create(this);
        try
        {
            var token = await CookieService.GetItemAsync("Web-AM-Connect-Key");
            if (string.IsNullOrEmpty(token))
            {
                await JS.InvokeVoidAsync("alert", "인증 정보가 없습니다.");
                NavigationManager.NavigateTo("/");
                return;
            }

            // AppController를 통해 세션에서 snsId 가져오기
            var request = new HttpRequestMessage(HttpMethod.Get, $"/api/v1/in/app/session/get?key=snsId");
            request.Headers.Add("Web-AM-Connect-Key", token);

            var response = await Http.SendAsync(request);
            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadFromJsonAsync<JsonElement>();
                LoggerService.Write($"세션 응답: {content}");

                if (content.TryGetProperty("status", out var statusElement) &&
                    statusElement.TryGetProperty("code", out var codeElement) &&
                    codeElement.GetString() == "000")
                {
                    if (content.TryGetProperty("data", out var dataElement) &&
                        dataElement.TryGetProperty("data", out var snsIdElement))
                    {
                        snsId = snsIdElement.GetString() ?? "";
                        LoggerService.Write($"서버 세션에서 가져온 SNS ID: {snsId}");
                    }
                }
                else
                {
                    LoggerService.Write($"세션 데이터 가져오기 실패: {content}");
                }
            }
            else
            {
                LoggerService.Write($"세션 API 호출 실패: {response.StatusCode}");
            }

            if (string.IsNullOrEmpty(snsId))
            {
                LoggerService.Write("SNS ID가 없습니다.");
                await JS.InvokeVoidAsync("alert", "잘못된 접근입니다.");
                NavigationManager.NavigateTo("/");
            }
        }
        catch (Exception ex)
        {
            LoggerService.Write($"SNS ID 가져오기 실패: {ex.Message}");
            await JS.InvokeVoidAsync("alert", "세션 정보를 가져오는데 실패했습니다.");
            NavigationManager.NavigateTo("/");
        }
    }

    private void UpdateBirthDate()
    {
        if (int.TryParse(birthYear, out int year) &&
            int.TryParse(birthMonth, out int month) &&
            int.TryParse(birthDay, out int day))
        {
            try
            {
                birth = new DateTime(year, month, day);
            }
            catch (ArgumentOutOfRangeException)
            {
                birth = null;
            }
        }
        else
        {
            birth = null;
        }
    }

    private async Task ConfirmData()
    {
        if (string.IsNullOrWhiteSpace(name))
        {
            await JS.InvokeVoidAsync("alert", "이름을 입력해주세요.");
            return;
        }

        if (string.IsNullOrWhiteSpace(email))
        {
            await JS.InvokeVoidAsync("alert", "이메일을 입력해주세요.");
            return;
        }

        // 생일 업데이트
        UpdateBirthDate();

        // 전화번호 조합
        if (phonePart1.Length == 3 && phonePart2.Length == 4 && phonePart3.Length == 4)
        {
            phone = $"{phonePart1}-{phonePart2}-{phonePart3}";
        }
        else
        {
            await JS.InvokeVoidAsync("alert", "전화번호를 올바르게 입력해주세요.");
            return;
        }

        var registerData = new
        {
            name = name,
            birth = birth,
            email = email,
            phone = phone,
            address = address,
            sns_id = snsId,
            sns_type = "ST01",
            type = "UT05",
            device_id = "",
            auto_login_yn = false,
            login_date = DateTime.Now,
            push_token = "",
            location_yn = false,
            camera_yn = false,
            photo_yn = false,
            push_yn = false,
            market_app_yn = false,
            market_sms_yn = false,
            market_email_yn = false
        };

        try
        {
            LoadingService.ShowLoading();
            var token = await CookieService.GetItemAsync("Web-AM-Connect-Key");
            LoggerService.Write($"쿠키에서 가져온 토큰: '{token}'");

            if (string.IsNullOrEmpty(token))
            {
                await JS.InvokeVoidAsync("alert", "인증 정보가 없습니다.");
                NavigationManager.NavigateTo("/");

                LoadingService.HideLoading();
                return;
            }

            var request = new HttpRequestMessage(HttpMethod.Post, "/api/v1/in/user/register");
            request.Headers.Add("Web-AM-Connect_Key", token);
            LoggerService.Write($"요청 헤더: {string.Join(", ", request.Headers.Select(h => $"{h.Key}: {string.Join(", ", h.Value)}"))}");

            request.Content = JsonContent.Create(registerData);

            var response = await Http.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadFromJsonAsync<JsonElement>();
                var status = result.GetProperty("status");
                var code = status.GetProperty("code").GetString();
                var message = status.GetProperty("message").GetString();

                if (code == "000")
                {
                    var data = result.GetProperty("data");
                    var newToken = data.GetProperty("token").GetString();
                    var refresh = data.GetProperty("refresh").GetString();

                    // 서버 세션에 토큰 저장
                    var sessionReq = new HttpRequestMessage(HttpMethod.Post, "/api/v1/in/app/session/set");
                    sessionReq.Headers.Add("Web-AM-Connect-Key", token);
                    sessionReq.Content = JsonContent.Create(new[] {
                        new { key = "token", value = newToken },
                        new { key = "refresh", value = refresh }
                    });
                    var sessionResponse = await Http.SendAsync(sessionReq);

                    // 세션 스토리지 정리
                    await JS.InvokeVoidAsync("sessionStorage.removeItem", "snsId");

                    LoadingService.HideLoading();  
                    await JS.InvokeVoidAsync("alert", "회원가입이 완료되었습니다.");
                    NavigationManager.NavigateTo("/");
                }
                else
                {
                    LoadingService.HideLoading();
                    await JS.InvokeVoidAsync("alert", $"회원가입에 실패하였습니다.\n잠시 후 다시 시도해주세요.");
                }
            }
            else
            {
                LoadingService.HideLoading();
                await JS.InvokeVoidAsync("alert", "회원가입 중 오류가 발생했습니다.\n잠시 후 다시 시도해주세요.");
            }
        }
        catch (Exception ex)
        {
            LoadingService.HideLoading();
            LoggerService.Write($"예외 발생: {ex.Message}");
            await JS.InvokeVoidAsync("alert", "회원가입 중 오류가 발생했습니다.\n잠시 후 다시 시도해주세요.");
        }
    }

    private void SubmitPhone()
    {
        if (phonePart1.Length == 3 && phonePart2.Length == 4 && phonePart3.Length == 4)
        {
            var fullPhone = $"{phonePart1}-{phonePart2}-{phonePart3}";
            LoggerService.Write($"입력된 전화번호: {fullPhone}");
        }
        else
        {
            LoggerService.Write("전화번호를 올바르게 입력해주세요.");
        }
    }

    private async Task OpenDatePicker()
    {
        try
        {
            if (birth == null) birth = DateTime.Now;
            // showPicker 대신 click() 이벤트를 발생시켜 달력을 표시
            await JS.InvokeVoidAsync("eval", $"document.querySelector('input[type=\"date\"]').click()");
        }
        catch (Exception ex)
        {
            LoggerService.Write($"달력 표시 오류: {ex.Message}");
        }
    }
    private void OnBirthChanged(ChangeEventArgs e)
    {
        LoggerService.Write($"선택된 생일: {birth}");

    }


    private DotNetObjectReference<Register> objRef;

    protected override void OnInitialized()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    protected async Task OnClickAddress()
    {
        await JS.InvokeVoidAsync("openKakaoPostcodePopup", objRef);
    }

    [JSInvokable]
    public void SetAddress(string roadAddress, string jibunAddress, string zonecode)
    {
        address = roadAddress;
        LoggerService.Write($"SetAddress 호출됨: {roadAddress}, {jibunAddress}, {zonecode}");
        StateHasChanged();
    }
}