import { useEffect, useMemo, useRef, useState } from 'react';
import { AgCharts } from 'ag-charts-react';
import type { AgCartesianChartOptions } from 'ag-charts-community';
import { ModuleRegistry } from 'ag-charts-community';
import {
  AnnotationsModule,
  ContextMenuModule,
  CrosshairModule,
  LicenseManager,
  ZoomModule,
} from 'ag-charts-enterprise';
import { AG_CHARTS_LOCALE_ZH_CN } from 'ag-charts-locale';

LicenseManager.setLicenseKey('[v3][RELEASE][0102]_NDg2Njc4MzY3MDgzNw==16d78ca762fb5d2ff740aed081e2af7b');
ModuleRegistry.registerModules([AnnotationsModule, ContextMenuModule, ZoomModule, CrosshairModule]);

const yearlyCostData = [
  { year: '2021', cost: 2200000, buildingArea: 18600, builtArea: 17200, usableArea: 14800 },
  { year: '2022', cost: 2500000, buildingArea: 19100, builtArea: 17600, usableArea: 15300 },
  { year: '2023', cost: 3450000, buildingArea: 20600, builtArea: 19000, usableArea: 16400 },
  { year: '2024', cost: 9600000, buildingArea: 24800, builtArea: 23200, usableArea: 20100 },
  { year: '2025', cost: null, buildingArea: null, builtArea: null, usableArea: null },
];

const metricOptions = [
  { key: 'cost', label: '造价（元）', shortLabel: '造价' },
  { key: 'buildingArea', label: '建筑面积指标（元/m²）', shortLabel: '建筑' },
  { key: 'builtArea', label: '建造面积指标（元/m²）', shortLabel: '建造' },
  { key: 'usableArea', label: '使用面积指标（元/m²）', shortLabel: '使用' },
] as const;

type MetricKey = (typeof metricOptions)[number]['key'];

function formatWan(value: number) {
  return `${Math.round(value / 10000).toLocaleString('zh-CN')}万`;
}

function App() {
  const workspaceRef = useRef<HTMLElement>(null);
  const chartFrameRef = useRef<HTMLDivElement>(null);
  const [metricKey, setMetricKey] = useState<MetricKey>('cost');
  const [metricMenuOpen, setMetricMenuOpen] = useState(false);

  const selectedMetric = metricOptions.find((option) => option.key === metricKey) ?? metricOptions[0];

  useEffect(() => {
    const frame = chartFrameRef.current;
    const fullscreenTarget = workspaceRef.current;
    if (!frame || !fullscreenTarget) return;

    const getFullscreenButton = () => frame.querySelector<HTMLButtonElement>('.chart-fullscreen-button');

    const syncFullscreenButton = () => {
      const button = getFullscreenButton();
      if (!button) return;

      let icon = button.querySelector<HTMLElement>('.ag-charts-myButton-fullScreen');
      if (!icon) {
        button.innerHTML = '<i class="anticon anticon-arrow-salt ag-charts-myButton-fullScreen ag-charts-diy-button"></i>';
        icon = button.querySelector<HTMLElement>('.ag-charts-myButton-fullScreen');
      }

      const isFullscreen = document.fullscreenElement === fullscreenTarget;
      button.classList.toggle('ag-charts-toolbar__button--active', isFullscreen);
      icon?.classList.toggle('anticon-arrow-salt', !isFullscreen);
      icon?.classList.toggle('anticon-shrink', isFullscreen);
    };

    const toggleFullscreen = () => {
      if (document.fullscreenElement === fullscreenTarget) {
        void document.exitFullscreen();
      } else {
        void fullscreenTarget.requestFullscreen();
      }
    };

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key !== 'F11') return;

      event.preventDefault();
      event.stopPropagation();
      toggleFullscreen();
    };

    const handleFullscreenChange = () => {
      syncFullscreenButton();
    };

    const handleToolbarClick = (event: MouseEvent) => {
      const target = event.target as Element | null;
      const button = target?.closest<HTMLButtonElement>(
        '.chart-fullscreen-button',
      );
      if (!button || !frame.contains(button)) return;

      event.preventDefault();
      event.stopPropagation();
      toggleFullscreen();
    };

    const handleToolbarKeyDown = (event: KeyboardEvent) => {
      if (event.key !== ' ' && event.key !== 'Enter') return;

      const target = event.target as Element | null;
      const button = target?.closest<HTMLButtonElement>(
        '.chart-fullscreen-button',
      );
      if (!button || !frame.contains(button)) return;

      event.preventDefault();
      event.stopPropagation();
      toggleFullscreen();
    };

    const suppressBrowserContextMenu = (event: MouseEvent) => {
      event.preventDefault();
    };

    const observer = new MutationObserver(syncFullscreenButton);
    document.addEventListener('keydown', handleKeyDown, true);
    document.addEventListener('fullscreenchange', handleFullscreenChange);
    document.addEventListener('contextmenu', suppressBrowserContextMenu);
    frame.addEventListener('contextmenu', suppressBrowserContextMenu);
    frame.addEventListener('click', handleToolbarClick, true);
    frame.addEventListener('keydown', handleToolbarKeyDown, true);
    observer.observe(frame, { childList: true, subtree: true });
    syncFullscreenButton();

    return () => {
      document.removeEventListener('keydown', handleKeyDown, true);
      document.removeEventListener('fullscreenchange', handleFullscreenChange);
      document.removeEventListener('contextmenu', suppressBrowserContextMenu);
      frame.removeEventListener('contextmenu', suppressBrowserContextMenu);
      frame.removeEventListener('click', handleToolbarClick, true);
      frame.removeEventListener('keydown', handleToolbarKeyDown, true);
      observer.disconnect();
    };
  }, []);

  const chartOptions = useMemo<AgCartesianChartOptions>(() => {
    const isCost = metricKey === 'cost';
    const chartData = yearlyCostData.map((datum) => ({
      year: datum.year,
      amount: datum.cost == null ? null : isCost ? datum.cost : Math.round((datum.cost / Number(datum[metricKey])) * 100) / 100,
    }));

    return {
      theme: {
        palette: {
          fills: ['#006f9b', '#ff7faa', '#00994d', '#ff8833', '#00a0dd'],
          strokes: ['#003f58', '#934962', '#004a25', '#914d1d', '#006288'],
        },
        params: {
          foregroundColor: '#262a33',
          backgroundColor: '#fff1e5',
          accentColor: '#0d7680',
          fontFamily: '"Microsoft YaHei", "PingFang SC", "Segoe UI", Arial, sans-serif',
          fontSize: 14,
          tooltipBackgroundColor: '#fff7ef',
          tooltipTextColor: '#262a33',
        },
      },
      locale: {
        localeText: AG_CHARTS_LOCALE_ZH_CN,
      },
      background: {
        fill: 'transparent',
      },
      padding: {
        top: 16,
        right: 16,
        bottom: 18,
        left: 24,
      },
      data: chartData,
      zoom: {
        enabled: true,
        anchorPointX: 'pointer',
        anchorPointY: 'pointer',
        buttons: {
          enabled: true,
          visible: 'hover',
          buttons: [
            { icon: 'zoom-out', value: 'zoom-out', section: 'zoom', tooltip: '缩小' },
            { icon: 'zoom-in', value: 'zoom-in', section: 'zoom', tooltip: '放大' },
            { icon: 'pan-left', value: 'pan-left', section: 'pan', tooltip: '左移' },
            { icon: 'pan-right', value: 'pan-right', section: 'pan', tooltip: '右移' },
            { icon: 'reset', value: 'reset', section: 'reset', tooltip: '重置' },
          ],
        },
      },
      contextMenu: {
        enabled: true,
        items: ['defaults'],
      },
      annotations: {
        enabled: true,
        toolbar: {
          buttons: [
            {
              icon: 'trend-line-drawing',
              value: 'line-menu',
              tooltip: 'Line Tool',
            },
            {
              icon: 'text-annotation',
              value: 'text-menu',
              tooltip: 'Text Tool',
            },
            {
              icon: 'arrow-drawing',
              value: 'shape-menu',
              tooltip: 'Shape Tool',
            },
            {
              icon: 'fibonacci-retracement-drawing',
              value: 'fibonacci-menu',
              tooltip: 'Fibonacci Tool',
            },
            {
              icon: 'delete',
              value: 'clear',
              tooltip: 'Clear annotations',
            },
          ],
        },
      },
      series: [
        {
          type: 'line',
          xKey: 'year',
          yKey: 'amount',
          yName: selectedMetric.label,
          stroke: '#0078a8',
          strokeWidth: 2,
          marker: {
            enabled: true,
            fill: '#0078a8',
            stroke: '#0078a8',
            size: 5,
          },
          interpolation: {
            type: 'smooth',
          },
        },
      ],
      axes: {
        x: {
          type: 'category',
          position: 'bottom',
          line: {
            enabled: true,
            stroke: '#c8b9a7',
          },
          tick: {
            enabled: false,
          },
          label: {
            color: '#1f2933',
            fontSize: 12,
          },
          crosshair: {
            snap: false,
          },
        },
        y: {
          type: 'number',
          position: 'left',
          title: {
            text: '',
          },
          label: {
            color: '#1f2933',
            fontSize: 12,
            formatter: ({ value }) =>
              isCost
                ? formatWan(Number(value))
                : Number(value).toLocaleString('zh-CN', {
                    minimumFractionDigits: 0,
                    maximumFractionDigits: 0,
                  }),
          },
          line: {
            enabled: false,
          },
          tick: {
            enabled: false,
          },
          gridLine: {
            enabled: true,
            style: [
              {
                stroke: '#e5d9ca',
                lineDash: [0],
              },
            ],
          },
          crosshair: {
            snap: false,
          },
        },
      },
      legend: {
        enabled: false,
      },
      tooltip: {
        enabled: true,
      },
    };
  }, [metricKey, selectedMetric.label]);

  return (
    <main className="dashboard-shell">
      <div className="watermark-layer" aria-hidden="true">
        {Array.from({ length: 18 }).map((_, index) => (
          <span key={index}>众为数字化管理平台</span>
        ))}
      </div>

      <section className="workspace" aria-label="年度费用模板" ref={workspaceRef}>
        <section className="chart-area" aria-label="年度总费用图表">
          <div className="chart-frame" ref={chartFrameRef}>
            <div className="metric-switcher">
              <button
                className="metric-switcher-button"
                type="button"
                title="切换纵坐标指标"
                aria-expanded={metricMenuOpen}
                aria-haspopup="menu"
                onClick={() => setMetricMenuOpen((open) => !open)}
              >
                {selectedMetric.label}
              </button>
              {metricMenuOpen ? (
                <div className="metric-switcher-menu" role="menu" aria-label="切换纵坐标指标">
                  {metricOptions.map((option) => (
                    <button
                      className="metric-switcher-menu-item"
                      type="button"
                      role="menuitem"
                      key={option.key}
                      aria-current={option.key === metricKey}
                      onClick={() => {
                        setMetricKey(option.key);
                        setMetricMenuOpen(false);
                      }}
                    >
                      {option.label}
                    </button>
                  ))}
                </div>
              ) : null}
            </div>
            <button className="chart-fullscreen-button ag-charts-toolbar__button" type="button" title="全屏(F11)">
              <i className="anticon anticon-arrow-salt ag-charts-myButton-fullScreen ag-charts-diy-button" />
            </button>
            <AgCharts options={chartOptions} />
          </div>
        </section>

        <aside className="right-placeholder" aria-label="右侧预留区域" />
      </section>
    </main>
  );
}

export default App;
