import { useEffect, useMemo, useRef, useState } from "react";
import CalendarMonthOutlined from "@mui/icons-material/CalendarMonthOutlined";
import KeyboardArrowDownOutlined from "@mui/icons-material/KeyboardArrowDownOutlined";
import PublicOutlined from "@mui/icons-material/PublicOutlined";
import { getTimeZoneLabel, lastDaysRange, rangeEndMs, rangeStartMs, sameRange, thisMonthRange, TIME_ZONE_OPTIONS, todayRange } from "../utils/time.js";

const defaultCountryOptions = [{ countryCode: "", id: 0, label: "全部国家", regionIds: [], searchText: "全部国家 all", value: 0 }];
const defaultRegionOptions = [{ countryCodes: [], id: "all", label: "全部区域", value: "all" }];
const rangeOptions = [
  { label: "今日", value: "today", getRange: (timeZone) => todayRange(timeZone) },
  { label: "近 7 日", value: "7d", getRange: (timeZone) => lastDaysRange(7, timeZone) },
  { label: "近 14 日", value: "14d", getRange: (timeZone) => lastDaysRange(14, timeZone) },
  { label: "近 30 日", value: "30d", getRange: (timeZone) => lastDaysRange(30, timeZone) },
  { label: "本月", value: "month", getRange: (timeZone) => thisMonthRange(timeZone) }
];
const weekLabels = ["一", "二", "三", "四", "五", "六", "日"];
const hours = Array.from({ length: 24 }, (_, index) => pad2(index));
const minutes = Array.from({ length: 60 }, (_, index) => pad2(index));
const seconds = minutes;

export function DatabiHeader({
  activeScreen = "overview",
  appCode,
  appOptions = [],
  countryId,
  countryOptions = defaultCountryOptions,
  error = "",
  filtersLoading = false,
  loading = false,
  onScreenChange,
  onAppChange,
  onCountryChange,
  onRangeChange,
  onRegionChange,
  onTimeZoneChange,
  onViewModeChange,
  range,
  regionId,
  regionOptions = defaultRegionOptions,
  timeZone,
  timeZoneOptions = TIME_ZONE_OPTIONS,
  viewMode = "report"
}) {
  const [openControl, setOpenControl] = useState("");
  const headerRef = useRef(null);
  const appLabel = appOptions.find((item) => item.code === appCode || item.value === appCode)?.label || appCode;
  const regionLabel = regionOptions.find((item) => String(item.id) === String(regionId) || String(item.value) === String(regionId))?.label || "全部区域";
  const timeZoneLabel = getTimeZoneLabel(timeZone);
  const filteredCountries = useMemo(() => {
    if (regionId === "all" || !regionOptions.some((item) => item.countryCodes?.length)) {
      return countryOptions;
    }
    return countryOptions.filter((item) => Number(item.id) === 0 || item.regionIds?.includes(String(regionId)) || item.regionId === regionId);
  }, [countryOptions, regionId, regionOptions]);
  const countryLabel = filteredCountries.find((item) => Number(item.id) === Number(countryId))?.label || "全部国家";
  const activeRange = rangeOptions.find((item) => {
    const next = item.getRange(timeZone);
    return sameRange(next, range);
  });

  useEffect(() => {
    const closeOnOutsideClick = (event) => {
      if (!headerRef.current?.contains(event.target)) {
        setOpenControl("");
      }
    };
    document.addEventListener("mousedown", closeOnOutsideClick);
    return () => document.removeEventListener("mousedown", closeOnOutsideClick);
  }, []);

  const toggleControl = (name) => {
    setOpenControl((current) => (current === name ? "" : name));
  };

  const selectItem = (callback, value) => {
    callback(value);
    setOpenControl("");
  };

  return (
    <header className="databi-header" ref={headerRef}>
      <div className="databi-header-left">
        <div className="brand-lockup">
          <div>
            <h1>数据中心</h1>
          </div>
        </div>
        <div className="view-mode-switch" role="tablist" aria-label="视图切换">
          <button aria-selected={viewMode === "report"} className={viewMode === "report" ? "is-active" : ""} onClick={() => onViewModeChange?.("report")} role="tab" type="button">
            报表视图
          </button>
          <button aria-selected={viewMode === "bigscreen"} className={viewMode === "bigscreen" ? "is-active" : ""} onClick={() => onViewModeChange?.("bigscreen")} role="tab" type="button">
            大屏 BI
          </button>
        </div>
      </div>
      <nav className="screen-switch" aria-label="数据大屏切换">
        <button className={activeScreen === "overview" ? "is-active" : ""} onClick={() => onScreenChange?.("overview")} type="button">
          运营总览
        </button>
        <button className={activeScreen === "selfGames" ? "is-active" : ""} onClick={() => onScreenChange?.("selfGames")} type="button">
          自研游戏
        </button>
      </nav>
      <div className="header-controls">
        <FilterMenu
          className="filter-control--timezone"
          icon={<span className="control-glyph">TZ</span>}
          isOpen={openControl === "timezone"}
          label="时区"
          onSelect={(value) => selectItem(onTimeZoneChange, value)}
          onToggle={() => toggleControl("timezone")}
          options={timeZoneOptions}
          value={timeZone}
          valueLabel={timeZoneLabel}
        />
        <FilterMenu
          className="filter-control--app"
          icon={<span className="control-glyph">APP</span>}
          isOpen={openControl === "app"}
          label="App"
          loading={filtersLoading}
          onSelect={(value) => selectItem(onAppChange, value)}
          onToggle={() => toggleControl("app")}
          options={appOptions.map((item) => ({ label: item.label, value: item.code }))}
          value={appCode}
          valueLabel={appLabel}
        />
        <RangeMenu
          activeValue={activeRange?.value}
          isOpen={openControl === "range"}
          onSelect={(nextRange) => selectItem(onRangeChange, nextRange)}
          onToggle={() => toggleControl("range")}
          range={range}
          timeZone={timeZone}
        />
        <FilterMenu
          icon={<PublicOutlined fontSize="small" />}
          isOpen={openControl === "region"}
          label="区域"
          loading={filtersLoading}
          onSelect={(value) => selectItem(onRegionChange, value)}
          onToggle={() => toggleControl("region")}
          options={regionOptions}
          value={regionId}
          valueLabel={regionLabel}
        />
        <SearchableFilterMenu
          icon={<span className="control-glyph">CN</span>}
          isOpen={openControl === "country"}
          label="国家"
          loading={filtersLoading}
          onSelect={(value) => selectItem(onCountryChange, Number(value))}
          onToggle={() => toggleControl("country")}
          options={filteredCountries}
          value={countryId}
          valueLabel={countryLabel}
        />
        <span className={error ? "live-dot live-dot--warn" : "live-dot"} title={error || ""}>
          {error ? "异常" : loading ? "刷新中" : "实时"}
        </span>
        {error ? <span className="header-error">{error}</span> : null}
      </div>
    </header>
  );
}

function FilterMenu({ className = "", icon, isOpen, label, loading = false, onSelect, onToggle, options, value, valueLabel }) {
  return (
    <div className={["filter-control", className].filter(Boolean).join(" ")}>
      <button aria-expanded={isOpen} className="filter-trigger" disabled={loading} onClick={onToggle} type="button">
        <span className="filter-label">
          {icon ? <span className="filter-icon">{icon}</span> : null}
          <span>{label}</span>
        </span>
        <span className="filter-value">{valueLabel}</span>
        <KeyboardArrowDownOutlined className="filter-chevron" fontSize="small" />
      </button>
      {isOpen ? (
        <div className="filter-popover" role="listbox">
          {loading ? <span className="filter-empty">加载中...</span> : null}
          {!loading && !options.length ? <span className="filter-empty">暂无选项</span> : null}
          {!loading
            ? options.map((item) => (
                <button className={item.value === value || item.id === value ? "is-active" : ""} key={item.value ?? item.id} onClick={() => onSelect(item.value ?? item.id)} role="option" type="button">
                  {item.label}
                </button>
              ))
            : null}
        </div>
      ) : null}
    </div>
  );
}

function SearchableFilterMenu({ icon, isOpen, label, loading = false, onSelect, onToggle, options, value, valueLabel }) {
  const [query, setQuery] = useState("");
  const filteredOptions = useMemo(() => {
    const keyword = query.trim().toLowerCase();
    if (!keyword) {
      return options;
    }
    return options.filter((item) => `${item.label || ""} ${item.countryCode || ""} ${item.searchText || ""}`.toLowerCase().includes(keyword));
  }, [options, query]);

  useEffect(() => {
    if (isOpen) {
      setQuery("");
    }
  }, [isOpen]);

  return (
    <div className="filter-control filter-control--country">
      <button aria-expanded={isOpen} className="filter-trigger" disabled={loading} onClick={onToggle} type="button">
        <span className="filter-label">
          {icon ? <span className="filter-icon">{icon}</span> : null}
          <span>{label}</span>
        </span>
        <span className="filter-value">{valueLabel}</span>
        <KeyboardArrowDownOutlined className="filter-chevron" fontSize="small" />
      </button>
      {isOpen ? (
        <div className="filter-popover filter-popover--searchable" role="listbox">
          <label className="filter-search">
            <span>搜索国家</span>
            <input placeholder="国家 / Code" type="text" value={query} onChange={(event) => setQuery(event.target.value)} />
          </label>
          {loading ? <span className="filter-empty">加载中...</span> : null}
          {!loading && !filteredOptions.length ? <span className="filter-empty">没有匹配国家</span> : null}
          {!loading && filteredOptions.length ? (
            <div className="filter-options-scroll">
              {filteredOptions.map((item) => (
                <button className={Number(item.id) === Number(value) ? "is-active" : ""} key={item.value ?? item.id} onClick={() => onSelect(item.value ?? item.id)} role="option" type="button">
                  <span>{item.label}</span>
                  {item.countryCode ? <small>{item.countryCode}</small> : null}
                </button>
              ))}
            </div>
          ) : null}
        </div>
      ) : null}
    </div>
  );
}

function RangeMenu({ activeValue, isOpen, onSelect, onToggle, range, timeZone }) {
  const options = rangeOptions.map((item) => ({ ...item, range: item.getRange(timeZone) }));
  const activeOption = options.find((item) => item.value === activeValue);
  const [draft, setDraft] = useState(() => normalizeRange(range));
  const [activeField, setActiveField] = useState("start");
  const [viewMonth, setViewMonth] = useState(() => monthDate(range.start));
  const [error, setError] = useState("");
  const calendarDays = useMemo(() => createCalendarDays(viewMonth), [viewMonth]);
  const activeTime = splitTime(draft[`${activeField}Time`]);

  useEffect(() => {
    if (isOpen) {
      const normalized = normalizeRange(range);
      setDraft(normalized);
      setActiveField("start");
      setViewMonth(monthDate(normalized.start));
      setError("");
    }
  }, [isOpen, range]);

  const changeMonth = (offset) => {
    setViewMonth((current) => new Date(current.getFullYear(), current.getMonth() + offset, 1));
  };

  const changeYear = (offset) => {
    setViewMonth((current) => new Date(current.getFullYear() + offset, current.getMonth(), 1));
  };

  const selectQuickRange = (nextRange) => {
    const normalized = normalizeRange(nextRange);
    setDraft(normalized);
    setActiveField("start");
    setViewMonth(monthDate(normalized.start));
    setError("");
  };

  const activateField = (field) => {
    setActiveField(field);
    setViewMonth(monthDate(draft[field]));
    setError("");
  };

  const selectDate = (date) => {
    const selectedValue = dateValue(date);
    setDraft((current) => ({ ...current, [activeField]: selectedValue }));
    if (activeField === "start") {
      setActiveField("end");
      setViewMonth(monthDate(selectedValue));
    }
    setError("");
  };

  const selectTime = (part, value) => {
    setDraft((current) => ({ ...current, [`${activeField}Time`]: updateTimePart(current[`${activeField}Time`], part, value) }));
    setError("");
  };

  const applyDraft = () => {
    const normalized = normalizeRange(draft);
    if (rangeStartMs(normalized, timeZone) > rangeEndMs(normalized, timeZone)) {
      setError("结束时间必须晚于开始时间");
      return;
    }
    onSelect(normalized);
  };

  return (
    <div className="filter-control filter-control--range">
      <button aria-expanded={isOpen} aria-haspopup="listbox" className="date-range-trigger" onClick={onToggle} type="button">
        <span className="date-range-label">
          <CalendarMonthOutlined fontSize="inherit" />
          <span>{activeOption?.label || "时间范围"}</span>
        </span>
        <span className="date-range-values">
          <b>{range.start}</b>
          <i>~</i>
          <b>{range.end}</b>
        </span>
        <KeyboardArrowDownOutlined className="date-range-chevron" fontSize="small" />
      </button>
      {isOpen ? (
        <div className="date-time-popover" role="dialog">
          <div className="date-time-shortcuts" role="listbox">
            {options.map((item) => (
              <button aria-selected={sameRange(item.range, draft)} className={sameRange(item.range, draft) ? "is-active" : ""} key={item.value} onClick={() => selectQuickRange(item.range)} role="option" type="button">
                {item.label}
              </button>
            ))}
          </div>
          <div className="date-time-fields" role="tablist">
            <button aria-selected={activeField === "start"} className={activeField === "start" ? "is-active" : ""} onClick={() => activateField("start")} role="tab" type="button">
              <span>开始时间</span>
              <b>{formatDateTimePart(draft.start, draft.startTime)}</b>
            </button>
            <button aria-selected={activeField === "end"} className={activeField === "end" ? "is-active" : ""} onClick={() => activateField("end")} role="tab" type="button">
              <span>结束时间</span>
              <b>{formatDateTimePart(draft.end, draft.endTime)}</b>
            </button>
          </div>
          <div className="date-time-picker">
            <div className="calendar-pane">
              <div className="calendar-toolbar">
                <button aria-label="上一年" onClick={() => changeYear(-1)} type="button">«</button>
                <button aria-label="上个月" onClick={() => changeMonth(-1)} type="button">‹</button>
                <strong>{viewMonth.getFullYear()}年 {viewMonth.getMonth() + 1}月</strong>
                <button aria-label="下个月" onClick={() => changeMonth(1)} type="button">›</button>
                <button aria-label="下一年" onClick={() => changeYear(1)} type="button">»</button>
              </div>
              <div className="calendar-grid">
                {weekLabels.map((label) => (
                  <span className="calendar-weekday" key={label}>{label}</span>
                ))}
                {calendarDays.map((date) => {
                  const value = dateValue(date);
                  const className = [
                    "calendar-day",
                    date.getMonth() !== viewMonth.getMonth() ? "is-muted" : "",
                    value === draft.start ? "is-start" : "",
                    value === draft.end ? "is-end" : "",
                    isBetween(value, draft.start, draft.end) ? "is-between" : "",
                    value === draft[activeField] ? "is-active" : ""
                  ].filter(Boolean).join(" ");
                  return (
                    <button className={className} key={value} onClick={() => selectDate(date)} type="button">
                      {date.getDate()}
                    </button>
                  );
                })}
              </div>
            </div>
            <div className="time-pane" aria-label="时间">
              <TimeColumn label="时" onSelect={(value) => selectTime("hour", value)} options={hours} value={activeTime.hour} />
              <TimeColumn label="分" onSelect={(value) => selectTime("minute", value)} options={minutes} value={activeTime.minute} />
              <TimeColumn label="秒" onSelect={(value) => selectTime("second", value)} options={seconds} value={activeTime.second} />
            </div>
          </div>
          <div className="date-time-footer">
            {error ? <span>{error}</span> : <span>{formatRange(draft)}</span>}
            <button onClick={applyDraft} type="button">确定</button>
          </div>
        </div>
      ) : null}
    </div>
  );
}

function TimeColumn({ label, onSelect, options, value }) {
  return (
    <div className="time-column">
      <span>{label}</span>
      <div>
        {options.map((item) => (
          <button className={item === value ? "is-active" : ""} key={item} onClick={() => onSelect(item)} type="button">
            {item}
          </button>
        ))}
      </div>
    </div>
  );
}

function dateValue(date) {
  return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;
}

function formatRange(range) {
  return `${formatDateTimePart(range.start, range.startTime)} ~ ${formatDateTimePart(range.end, range.endTime)}`;
}

function formatDateTimePart(date, time) {
  return `${date} ${normalizeTime(time)}`;
}

function normalizeRange(range) {
  return {
    end: range?.end || dateValue(new Date()),
    endTime: normalizeTime(range?.endTime || "23:59:59"),
    start: range?.start || dateValue(new Date()),
    startTime: normalizeTime(range?.startTime || "00:00:00")
  };
}

function monthDate(value) {
  const [year, month] = String(value || dateValue(new Date())).split("-").map(Number);
  return new Date(year || new Date().getFullYear(), (month || 1) - 1, 1);
}

function createCalendarDays(viewMonth) {
  const firstDay = new Date(viewMonth.getFullYear(), viewMonth.getMonth(), 1);
  const mondayIndex = (firstDay.getDay() + 6) % 7;
  const start = new Date(firstDay);
  start.setDate(firstDay.getDate() - mondayIndex);
  return Array.from({ length: 42 }, (_, index) => {
    const date = new Date(start);
    date.setDate(start.getDate() + index);
    return date;
  });
}

function isBetween(value, start, end) {
  return value > start && value < end;
}

function splitTime(value) {
  const [hour, minute, second] = normalizeTime(value).split(":");
  return { hour, minute, second };
}

function updateTimePart(value, part, nextValue) {
  const parts = splitTime(value);
  return [part === "hour" ? nextValue : parts.hour, part === "minute" ? nextValue : parts.minute, part === "second" ? nextValue : parts.second].join(":");
}

function normalizeTime(value) {
  const [hour = "00", minute = "00", second = "00"] = String(value || "00:00:00").split(":");
  return `${pad2(hour)}:${pad2(minute)}:${pad2(second)}`;
}

function pad2(value) {
  return String(value).padStart(2, "0");
}
