import { useEffect, useMemo, useState } from "react";
import { fetchMoneySession } from "./api.js";
import { CountryChannelPanel } from "./components/CountryChannelPanel.jsx";
import { MoneyHeader } from "./components/MoneyHeader.jsx";
import { MoneyOverview } from "./components/MoneyOverview.jsx";
import { MONEY_VIEWS, MoneySidebar } from "./components/MoneySidebar.jsx";
import { OperatorPerformancePanel } from "./components/OperatorPerformancePanel.jsx";
import { PaymentLinkPanel } from "./components/PaymentLinkPanel.jsx";
import { PerformanceTable } from "./components/PerformanceTable.jsx";
import {
  filterMoneyModules,
  moneyAppOptions,
  moneyCountries,
  moneyOperators,
  summarizeMoneyModules
} from "./data.js";
import {
  appOptionsFromMasterData,
  countryOptionsFromMasterData,
  fetchMoneyMasterData,
  regionOptionsFromMasterData
} from "./masterDataApi.js";

const emptyMasterData = { apps: [], countries: [], error: "", loading: false, modules: [], performanceSummary: {}, regions: [], scopes: [] };

export function MoneyApp() {
  const [sessionState, setSessionState] = useState({ error: "", loading: true, session: null });
  const [masterDataState, setMasterDataState] = useState(emptyMasterData);
  const [activeView, setActiveView] = useState("overview");
  const [mode, setMode] = useState("finance");
  const [activeOperatorId, setActiveOperatorId] = useState("sarah-ali");
  const [appCode, setAppCode] = useState("");
  const [countryCode, setCountryCode] = useState("");
  const [regionId, setRegionId] = useState("");
  const [operatorKeyword, setOperatorKeyword] = useState("");
  const [links, setLinks] = useState([]);
  const [toast, setToast] = useState("");

  useEffect(() => {
    let mounted = true;
    fetchMoneySession()
      .then((session) => {
        if (mounted) {
          setSessionState({ error: "", loading: false, session });
        }
      })
      .catch((err) => {
        if (mounted) {
          setSessionState({ error: err.message || "会话校验失败", loading: false, session: null });
        }
      });
    return () => {
      mounted = false;
    };
  }, []);

  useEffect(() => {
    if (!sessionState.session?.canViewMoney) {
      return undefined;
    }
    let mounted = true;
    setMasterDataState((current) => ({ ...current, error: "", loading: true }));
    fetchMoneyMasterData()
      .then((data) => {
        if (mounted) {
          setMasterDataState({ ...data, loading: false });
        }
      })
      .catch((err) => {
        if (mounted) {
          setMasterDataState({ ...emptyMasterData, error: err.message || "主数据加载失败", loading: false });
        }
      });
    return () => {
      mounted = false;
    };
  }, [sessionState.session?.canViewMoney]);

  const appOptions = useMemo(() => appOptionsFromMasterData(masterDataState.apps, moneyAppOptions), [masterDataState.apps]);
  const countryOptions = useMemo(
    () => countryOptionsFromMasterData(masterDataState.countries, moneyCountries),
    [masterDataState.countries]
  );
  const regionOptions = useMemo(() => regionOptionsFromMasterData(masterDataState.regions), [masterDataState.regions]);

  useEffect(() => {
    if (appCode && !hasOption(appOptions, appCode)) {
      setAppCode("");
    }
  }, [appCode, appOptions]);

  useEffect(() => {
    if (countryCode && !hasOption(countryOptions, countryCode)) {
      setCountryCode("");
    }
  }, [countryCode, countryOptions]);

  useEffect(() => {
    if (regionId && !hasOption(regionOptions, regionId)) {
      setRegionId("");
    }
  }, [regionId, regionOptions]);

  const filteredModules = useMemo(
    () =>
      filterMoneyModules({
        activeOperatorId,
        appCode,
        countryCode,
        mode,
        modules: masterDataState.modules,
        operatorKeyword: mode === "finance" ? operatorKeyword : "",
        regionId,
        regions: masterDataState.regions
      }),
    [activeOperatorId, appCode, countryCode, masterDataState.modules, masterDataState.regions, mode, operatorKeyword, regionId]
  );
  const summary = useMemo(() => summarizeMoneyModules(filteredModules), [filteredModules]);
  const visibleModuleIds = useMemo(() => new Set(filteredModules.map((module) => module.id)), [filteredModules]);
  const visibleLinks = useMemo(() => links.filter((link) => visibleModuleIds.has(link.moduleId)), [links, visibleModuleIds]);
  const operators = useMemo(() => operatorsFromModules(masterDataState.modules), [masterDataState.modules]);
  const activeOperator = operators.find((operator) => operator.id === activeOperatorId) || operators[0] || moneyOperators[0];
  const view = MONEY_VIEWS.find((item) => item.id === activeView) || MONEY_VIEWS[0];

  const resetFilters = () => {
    setAppCode("");
    setCountryCode("");
    setRegionId("");
    setOperatorKeyword("");
  };

  const showToast = (message) => {
    setToast(message);
    window.setTimeout(() => setToast(""), 1600);
  };

  const copyLink = async (value) => {
    await copyText(value);
    showToast("链接已复制");
  };

  const addPaymentLink = (link) => {
    setLinks((current) => [link, ...current.filter((item) => (item.orderId || item.id) !== (link.orderId || link.id))]);
    showToast("支付链接已创建");
  };

  const exportReport = () => {
    downloadTextFile(createCsv(filteredModules), `hyapp-money-${Date.now()}.csv`);
    showToast("财务报表已导出");
  };

  if (sessionState.loading) {
    return <StateScreen title="正在进入财务系统" />;
  }

  if (sessionState.error) {
    return <StateScreen title={sessionState.error} />;
  }

  if (!sessionState.session?.canViewMoney) {
    return <StateScreen title="无 money:view" />;
  }

  return (
    <main className="money-shell">
      <MoneySidebar
        activeOperator={activeOperator}
        activeView={activeView}
        mode={mode}
        onModeChange={setMode}
        onViewChange={setActiveView}
        session={sessionState.session}
        summary={summary}
      />
      <section className="money-main">
        <MoneyHeader
          activeOperatorId={activeOperatorId}
          appCode={appCode}
          appOptions={appOptions}
          countryCode={countryCode}
          countryOptions={countryOptions}
          masterDataError={masterDataState.error}
          masterDataLoading={masterDataState.loading}
          mode={mode}
          onActiveOperatorChange={setActiveOperatorId}
          onAppChange={setAppCode}
          onCountryChange={setCountryCode}
          onExport={exportReport}
          onOperatorKeywordChange={setOperatorKeyword}
          onRegionChange={setRegionId}
          onReset={resetFilters}
          operatorKeyword={operatorKeyword}
          operators={operators}
          regionId={regionId}
          regionOptions={regionOptions}
          view={view}
        />
        <div className="money-content">
          {renderContent(activeView, {
            copyLink,
            countries: masterDataState.countries,
            filteredModules,
            onPaymentLinkCreated: addPaymentLink,
            regions: masterDataState.regions,
            summary,
            visibleLinks
          })}
        </div>
      </section>
      {toast ? <div className="money-toast">{toast}</div> : null}
    </main>
  );
}

function renderContent(activeView, { copyLink, countries, filteredModules, onPaymentLinkCreated, regions, summary, visibleLinks }) {
  if (activeView === "modules") {
    return <PerformanceTable meta={`${filteredModules.length} 个区域`} modules={filteredModules} summary={summary} title="区域绩效" />;
  }

  if (activeView === "operators") {
    return <OperatorPerformancePanel modules={filteredModules} />;
  }

  if (activeView === "payments") {
    return <PaymentLinkPanel links={visibleLinks} modules={filteredModules} onCopy={copyLink} onCreated={onPaymentLinkCreated} />;
  }

  if (activeView === "countries") {
    return <CountryChannelPanel countries={countries} links={visibleLinks} modules={filteredModules} regions={regions} />;
  }

  return <MoneyOverview links={visibleLinks} modules={filteredModules} summary={summary} />;
}

function hasOption(options, value) {
  return options.some(([optionValue]) => String(optionValue) === String(value));
}

function StateScreen({ detail = "", title }) {
  return (
    <main className="money-shell money-shell--state">
      <section className="money-state">
        <h1>{title}</h1>
        {detail ? <p>{detail}</p> : null}
      </section>
    </main>
  );
}

function createCsv(modules) {
  const header = ["区域", "负责人", "国家", "充值USD", "流水USD", "存量工资USD", "新增", "日活", "当日目标USD", "当月目标USD"];
  const rows = modules.map((module) => [
    module.moduleName,
    module.operatorName,
    module.countryName,
    module.rechargeUsd,
    module.revenueUsd,
    module.salaryUsd,
    module.newUsers,
    module.dau,
    module.dayTargetUsd,
    module.monthTargetUsd
  ]);
  return [header, ...rows].map((row) => row.map(csvCell).join(",")).join("\n");
}

function operatorsFromModules(modules) {
  const seen = new Set();
  return modules
    .map((module) => ({
      department: module.department || "",
      id: module.operatorId,
      label: module.operatorName || module.operatorId
    }))
    .filter((operator) => {
      if (!operator.id || seen.has(operator.id)) {
        return false;
      }
      seen.add(operator.id);
      return true;
    });
}

function csvCell(value) {
  const text = String(value ?? "");
  return /[",\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text;
}

function downloadTextFile(content, filename) {
  const blob = new Blob([content], { type: "text/csv;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  link.remove();
  URL.revokeObjectURL(url);
}

async function copyText(value) {
  if (navigator.clipboard?.writeText) {
    try {
      await navigator.clipboard.writeText(value);
      return;
    } catch {
      // 本地 HTTP 调试时浏览器可能拒绝 Clipboard API，退回同步复制以保证财务能拿到刚生成的收款链接。
    }
  }
  const input = document.createElement("textarea");
  input.value = value;
  input.setAttribute("readonly", "");
  input.style.position = "fixed";
  input.style.opacity = "0";
  document.body.appendChild(input);
  input.select();
  document.execCommand("copy");
  input.remove();
}
