'use client';
import React, { useEffect, useMemo, useRef } from 'react';
import { useSearchParams } from 'next/navigation';
import { useSession } from 'next-auth/react';
import { Button, Statistic, Typography } from 'antd';
import { DownloadOutlined } from '@ant-design/icons';
import Highcharts from 'highcharts';
import { useRoles } from '@/hooks/useRoles';
import theme from '@/app/theme/themeConfig';

const { Title, Text } = Typography;

const PRIMARY_COLOR = theme.token?.colorPrimary || '#0E8744';

const TAB_LABELS: Record<string, string> = {
  visited: 'Visits',
  token: 'Tokens',
  booked: 'Bookings',
};

const VIEW_TYPE_LABELS: Record<string, string> = {
  self_view: 'Self View',
  partner_view: 'Partner View',
  combine_view: 'Combine View',
};

const capitalize = (value: string): string =>
  value
    .split('-')
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
    .join('-');

// Fixed print size for the chart — comfortably within a landscape A4/Letter
// page after the 16mm padding on each side, regardless of how wide the
// on-screen browser window happens to be when the chart first renders.
const PRINT_CHART_WIDTH = 900;
const PRINT_CHART_HEIGHT = 480;

interface ReportDataItem {
  source: string;
  count: number;
}

// Standalone report view for the Source Quality Overall widget, opened in a new
// tab via window.open() from SourceQualityOverall.tsx's "Print Report" button.
// Being its own route (rather than printing the live dashboard in place) means:
// no other dashboard widgets to hide, no shared chart instance to resize and
// restore, and a plain window.print() works fine since this page has nothing
// else on it — see SourceQualityOverall.tsx for the history of why in-place
// printing kept breaking.
//
// The chart data is passed straight through in the URL (SourceQualityOverall
// already has it loaded) rather than re-fetched here — this is a separate
// tab/store, so nothing carries over automatically, but there's no need to
// hit the API again for data the opener already has.
const SourceQualityReportPage: React.FC = () => {
  const searchParams = useSearchParams();
  const { data: session } = useSession();
  const refContainer = useRef<HTMLDivElement | null>(null);
  const chartInstanceRef = useRef<Highcharts.Chart | null>(null);
  const { getRoleByName, getRoleById } = useRoles();

  const tab = searchParams.get('tab') || 'visited';
  const startDate = searchParams.get('start_date') || undefined;
  const endDate = searchParams.get('end_date') || undefined;
  const launchName = searchParams.get('launch_name');
  const roleName = searchParams.get('lead_user_role_name');
  const viewData = searchParams.get('veiw_data');
  const leadUserName = searchParams.get('lead_user_name');

  const reportData = useMemo<ReportDataItem[]>(() => {
    const raw = searchParams.get('data');
    if (!raw) {
      return [];
    }
    try {
      const parsed = JSON.parse(raw);
      return Array.isArray(parsed) ? parsed : [];
    } catch {
      return [];
    }
    // Only the URL's own data param matters — it's fixed for the lifetime of
    // this tab.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (!refContainer.current) {
      return;
    }
    const categories = reportData.map((item) => capitalize(item.source || ''));
    const seriesData = reportData.map((item) => item.count);

    const chart = Highcharts.chart(refContainer.current, {
      chart: {
        type: 'column',
      },
      title: {
        text: '',
      },
      xAxis: {
        categories,
        crosshair: true,
        title: {
          text: 'Source',
        },
      },
      yAxis: {
        min: 0,
        title: {
          text: TAB_LABELS[tab] || 'Count',
        },
      },
      credits: {
        enabled: false,
      },
      legend: {
        enabled: false,
      },
      series: [
        {
          type: 'column',
          name: TAB_LABELS[tab] || 'Count',
          data: seriesData,
          pointWidth: 40,
          color: PRIMARY_COLOR,
        },
      ],
    });

    if (seriesData.length === 0) {
      chart.showLoading('No data available');
    }

    chartInstanceRef.current = chart;
  }, [reportData, tab]);

  // Highcharts bakes a fixed pixel width into the chart's SVG from whatever
  // the on-screen container measured at render time. CSS alone can't shrink
  // that for print, so it just overflows and crops on the right — worse, it's
  // inconsistent, since it depends on how wide the browser window happened to
  // be. Force an explicit, print-safe size *before* calling print() — doing
  // this on 'beforeprint' instead is unreliable, since there's no guarantee
  // the @media print layout has already been applied by the time that event
  // fires. Reflow back to responsive sizing afterwards so the on-screen view
  // (this tab typically stays open after printing) isn't left at print size.
  useEffect(() => {
    const handleAfterPrint = () => {
      chartInstanceRef.current?.setSize(null, null, false);
    };
    window.addEventListener('afterprint', handleAfterPrint);
    return () => window.removeEventListener('afterprint', handleAfterPrint);
  }, []);

  const handleDownloadPdf = () => {
    chartInstanceRef.current?.setSize(PRINT_CHART_WIDTH, PRINT_CHART_HEIGHT, false);
    window.print();
  };

  const metricLabel = TAB_LABELS[tab] || tab;
  const totalCount = reportData.reduce((sum, item) => sum + (item.count || 0), 0);
  const rangeSummary = startDate && endDate ? `${startDate} to ${endDate}` : 'All time';
  const viewLabel = viewData ? VIEW_TYPE_LABELS[viewData] || viewData : null;

  // A hierarchy dropdown selection (lead_user_role_name is only ever set once
  // one is picked) takes priority; otherwise this report is scoped to whoever
  // is currently logged in.
  const isHierarchySelection = Boolean(roleName);
  const roleLabel = roleName ? getRoleByName(roleName)?.label || capitalize(roleName) : null;
  const sessionRoleId = session?.user?.role?.id;
  const sessionRoleLabel = sessionRoleId != null ? getRoleById(sessionRoleId)?.label : null;

  const contextLine = useMemo(() => {
    const parts = [
      `Metric: ${metricLabel}`,
      `Date range: ${rangeSummary}`,
      `Launch: ${launchName || 'All launches'}`,
    ];
    if (isHierarchySelection) {
      const who = leadUserName ? `${leadUserName}${roleLabel ? ` (${roleLabel})` : ''}` : roleLabel;
      if (who) {
        parts.push(`Viewing as: ${who}${viewLabel ? ` — ${viewLabel}` : ''}`);
      }
    } else if (session?.user?.name) {
      parts.push(`Generated by: ${session.user.name}${sessionRoleLabel ? ` (${sessionRoleLabel})` : ''}`);
    }
    return parts.join('  ·  ');
  }, [metricLabel, rangeSummary, launchName, isHierarchySelection, leadUserName, roleLabel, viewLabel, session?.user?.name, sessionRoleLabel]);

  return (
    <div>
      <style>{`
        @media print {
          /* margin: 0 (not e.g. 16mm) is deliberate — Chrome's "Headers and
             footers" print option (URL, date, page number) only has room to
             draw inside the page's margin box. Zero margin leaves it nowhere
             to render, regardless of that checkbox. The 16mm inset is
             recreated below as padding on the content itself instead. */
          @page { size: landscape; margin: 0; }
          .site-header,
          .custom-sidebar,
          .report-no-print {
            display: none !important;
          }
          .after-login-main-content {
            height: auto !important;
            overflow: visible !important;
            padding: 16mm !important;
          }
          /* Belt-and-suspenders: the JS resize above targets a landscape
             A4/Letter page specifically. If the printer's actual paper is
             narrower than that, clamp instead of overflowing off the edge. */
          .report-chart svg {
            max-width: 100% !important;
            height: auto !important;
          }
        }
      `}</style>
      <div
        className="report-no-print"
        style={{ display: 'flex', justifyContent: 'flex-end', gap: 12, marginBottom: 16 }}
      >
        <Button onClick={() => window.close()}>Close</Button>
        {/* Same window.print() call as "Print" would use — there's no PDF library
            in this project, so "download" here means: open the browser's print
            dialog and pick "Save as PDF" as the destination. That's the only
            zero-dependency way to produce a real PDF file. */}
        <Button
          type="primary"
          icon={<DownloadOutlined />}
          onClick={handleDownloadPdf}
          disabled={!reportData.length}
        >
          Download PDF
        </Button>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}>
        <Title level={3} style={{ margin: 0 }}>Source Quality Overall</Title>
        <Statistic
          title={
            <Text strong style={{ color: PRIMARY_COLOR, fontSize: 18 }}>
              Total {metricLabel}
            </Text>
          }
          value={totalCount}
          valueStyle={{ color: PRIMARY_COLOR, fontWeight: 700, fontSize: 22 }}
        />
      </div>
      <Text type="secondary">{contextLine}</Text>
      {!reportData.length ? (
        <div>
          <Text type="secondary">No data available for the selected filters.</Text>
        </div>
      ) : null}
      <div className="report-chart" style={{ marginTop: 24 }}>
        <div ref={refContainer} />
      </div>
    </div>
  );
};

export default SourceQualityReportPage;
