#nullable enable
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.Locale;
namespace UVC.UIToolkit
{
///
/// UIToolkit 기반 날짜/시간 피커 모달.
/// 캘린더 그리드 + 시간 선택 + 범위 선택을 지원하는 날짜 선택 대화상자입니다.
///
///
/// DatePicker(날짜 피커)란?
///
/// DatePicker는 사용자가 달력에서 날짜를 선택할 수 있는 UI 컴포넌트입니다.
/// 예약 시스템, 일정 관리, 검색 필터 등에서 널리 사용됩니다.
/// 텍스트 입력보다 직관적이고 유효한 날짜만 선택할 수 있어 오류를 방지합니다.
///
///
/// 피커 모드 (PickerMode):
///
/// - DateOnly - 날짜만 선택
/// - DateAndTime - 날짜 + 시간(시/분) 선택
/// - DateRange - 시작일~종료일 범위 선택
/// - DateTimeRange - 시간 포함 범위 선택
///
///
/// UI 구성:
///
/// - 네비게이션 - 년/월 이동 버튼
/// - 요일 헤더 - 일~토 요일 표시 (로컬라이제이션 지원)
/// - 달력 그리드 - 6행 7열 (42일) 버튼
/// - 시간 선택 - 시/분 NumberStepper (DateAndTime 모드)
/// - 범위 정보 - 선택된 시작일/종료일 표시 (Range 모드)
///
///
/// 날짜 스타일:
///
/// - 오늘 - 테두리로 강조
/// - 선택된 날짜 - 배경색으로 강조
/// - 일요일 - 빨간색
/// - 토요일 - 파란색
/// - 범위 내 날짜 - 연한 배경색
///
///
/// 요일 이름 커스터마이징:
///
/// // 직접 지정
/// UTKDatePicker.SetDayNames(new[] { "일", "월", "화", "수", "목", "금", "토" });
///
/// // 로컬라이제이션 키 지정
/// UTKDatePicker.SetDayNameKeys(new[] { "day_sun", "day_mon", ... });
///
/// // 기본값으로 초기화
/// UTKDatePicker.ResetDayNames();
///
///
/// 실제 활용 예시:
///
/// - 예약 시스템 - 호텔, 항공권, 렌터카 예약일
/// - 일정 관리 - 이벤트, 회의, 마감일 설정
/// - 검색 필터 - 기간별 데이터 조회
/// - 생년월일 입력 - 회원 가입, 프로필 설정
///
///
///
///
/// // 기본 사용법 (날짜만)
/// var picker = UTKDatePicker.Show(rootVisualElement, DateTime.Today, UTKDatePicker.PickerMode.DateOnly, "Select Date");
/// picker.OnDateSelected += (date) =>
/// {
/// Debug.Log($"Date selected: {date:yyyy-MM-dd}");
/// };
///
/// // 날짜 + 시간 선택
/// var dateTimePicker = UTKDatePicker.Show(rootVisualElement, DateTime.Now, UTKDatePicker.PickerMode.DateAndTime, "Select Date & Time");
/// dateTimePicker.OnDateSelected += (date) =>
/// {
/// Debug.Log($"DateTime selected: {date:yyyy-MM-dd HH:mm}");
/// };
///
/// // async/await 사용법 (UniTask)
/// DateTime? selectedDate = await UTKDatePicker.ShowAsync(rootVisualElement, DateTime.Today);
/// if (selectedDate.HasValue)
/// {
/// Debug.Log($"Selected: {selectedDate.Value:yyyy-MM-dd}");
/// }
/// else
/// {
/// Debug.Log("Cancelled");
/// }
///
/// // 날짜 범위 선택
/// var rangePicker = UTKDatePicker.ShowRange(rootVisualElement, DateTime.Today, DateTime.Today.AddDays(7));
/// rangePicker.OnDateRangeSelected += (start, end) =>
/// {
/// Debug.Log($"Range selected: {start:yyyy-MM-dd} ~ {end:yyyy-MM-dd}");
/// };
///
/// // 날짜 범위 async/await 사용법
/// var result = await UTKDatePicker.ShowRangeAsync(rootVisualElement, DateTime.Today, DateTime.Today.AddDays(7));
/// if (result.HasValue)
/// {
/// Debug.Log($"Range: {result.Value.Start:yyyy-MM-dd} ~ {result.Value.End:yyyy-MM-dd}");
/// }
/// else
/// {
/// Debug.Log("Cancelled");
/// }
///
/// // 요일 이름 커스터마이징 (static - 모든 인스턴스에 적용)
/// UTKDatePicker.SetDayNames(new[] { "일", "월", "화", "수", "목", "금", "토" });
/// UTKDatePicker.SetDayNames(new[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" });
///
/// // 요일 이름 로컬라이제이션 키 설정
/// UTKDatePicker.SetDayNameKeys(new[] { "day_sun", "day_mon", "day_tue", "day_wed", "day_thu", "day_fri", "day_sat" });
///
/// // 요일 이름 기본값으로 초기화
/// UTKDatePicker.ResetDayNames();
///
/// // 인스턴스 직접 생성
/// var datePicker = new UTKDatePicker();
/// datePicker.SetDate(DateTime.Today);
/// container.Add(datePicker);
///
///
[UxmlElement]
public partial class UTKDatePicker : VisualElement, IDisposable
{
#region Enums
public enum PickerMode
{
DateOnly,
DateAndTime,
DateRange,
DateTimeRange
}
///
/// 범위 선택 시 현재 선택 중인 날짜 타입
///
private enum RangeSelectionState
{
SelectingStart,
SelectingEnd
}
#endregion
#region Constants
private const string UXML_PATH = "UIToolkit/Modal/UTKDatePicker";
private const string USS_PATH = "UIToolkit/Modal/UTKDatePicker";
private const int DAYS_IN_GRID = 42; // 6 rows x 7 columns
private static readonly string[] DEFAULT_DAY_NAME_KEYS = { "day_sun", "day_mon", "day_tue", "day_wed", "day_thu", "day_fri", "day_sat" };
#endregion
#region Static Fields
private static string[] s_dayNameKeys = DEFAULT_DAY_NAME_KEYS;
private static string[]? s_customDayNames;
#endregion
#region Fields
private bool _disposed;
private PickerMode _mode;
private DateTime _selectedDate = DateTime.Today;
private DateTime _displayMonth = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
// 범위 선택 관련 필드
private DateTime? _rangeStartDate;
private DateTime? _rangeEndDate;
private RangeSelectionState _rangeState = RangeSelectionState.SelectingStart;
private UTKModalBlocker? _blocker;
private readonly List