'use client';
import React, { useEffect, useRef, useState } from 'react';
import { Button, Col, DatePicker, Row, Spin, Statistic, Tabs, TabsProps, Typography } from 'antd';
import { FilePdfOutlined } from '@ant-design/icons';
import { AppDispatch, RootState } from '@/store/store';
import { useDispatch, useSelector } from 'react-redux';
import { fetchSourceQualityOverall, setSourceQualityOverallTab } from '../slice';
import Highcharts from 'highcharts';
import dayjs, { Dayjs } from 'dayjs';
import theme from '@/app/theme/themeConfig';

const { Title, Text } = Typography;
const { RangePicker } = DatePicker;

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

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

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

interface SourceQualityOverallProps {
  // Name of the user currently selected via the hierarchy dropdowns above the
  // dashboard, if any — resolved by page.tsx from DashboardProgressiveDropdownsTest's
  // selection chain. Passed through to the report page so it can show who the
  // report is scoped to without needing its own lookup.
  selectedUserName?: string | null;
}

const SourceQualityOverall: React.FC<SourceQualityOverallProps> = ({ selectedUserName }) => {
  const refContainer = useRef<HTMLDivElement | null>(null);
  const dispatch: AppDispatch = useDispatch();
  const {
    sourceQualityOverallTab,
    sourceQualityOverallData,
    sourceQualityOverallStatus,
    dashboardFilter,
  } = useSelector((state: RootState) => state.dashboard);

  // Separate date filter for this widget only — independent of the other
  // dashboard filters (which don't affect date filtering on any other widget).
  const [dateRange, setDateRange] = useState<[Dayjs | null, Dayjs | null] | null>(null);

  const handleTabChange = (value: string) => {
    dispatch(setSourceQualityOverallTab(value));
  };

  const handleDateChange = (dates: [Dayjs | null, Dayjs | null] | null) => {
    setDateRange(dates);
  };

  const disabledDate = (current: Dayjs): boolean => current.isAfter(dayjs().endOf('day'));

  // Only used to print a human-readable launch name in the PDF summary line.
  const filterLaunchLList = useSelector((state: RootState) => state?.allLeads?.filterLaunchLList);

  // Opens a dedicated report page (src/app/dashboard/source-quality-report)
  // in a new tab instead of printing the live dashboard in place. That page
  // renders nothing but this report — its own chart instance, sized for
  // landscape from the start — so there's no dashboard chrome to hide, no
  // shared chart to resize and restore, and a plain window.print() there
  // just works. This replaced an in-page @media print approach (ancestor
  // overflow clipping, extra blank pages) and then an isolated-iframe
  // approach (cropped chart from the live SVG's baked-in screen size) —
  // both fragile in ways a real, separately-rendered page isn't.
  //
  // The chart data is already loaded here, so it's passed straight through
  // as a URL param instead of having the report page re-fetch it — this
  // data is just source/count pairs, small enough to fit comfortably in a
  // URL.
  const handleOpenReport = () => {
    const params = new URLSearchParams();
    params.set('tab', sourceQualityOverallTab);
    params.set('data', JSON.stringify(sourceQualityOverallData));

    if (dateRange && dateRange[0] && dateRange[1]) {
      params.set('start_date', dateRange[0].format('YYYY-MM-DD'));
      params.set('end_date', dateRange[1].format('YYYY-MM-DD'));
    }
    if (dashboardFilter.launch_id) {
      params.set('launch_id', String(dashboardFilter.launch_id));
      const selectedLaunchName = filterLaunchLList?.find(
        (launch: { launch_id: string; launch_name: string }) => String(launch.launch_id) === String(dashboardFilter.launch_id)
      )?.launch_name;
      if (selectedLaunchName) {
        params.set('launch_name', selectedLaunchName);
      }
    }
    if (dashboardFilter.lead_user_city_id) {
      params.set('lead_user_city_id', String(dashboardFilter.lead_user_city_id));
    }
    if (dashboardFilter.lead_user_id) {
      params.set('lead_user_id', String(dashboardFilter.lead_user_id));
    }
    if (dashboardFilter.lead_user_role_name) {
      params.set('lead_user_role_name', dashboardFilter.lead_user_role_name);
    }
    if (dashboardFilter.veiw_data) {
      params.set('veiw_data', String(dashboardFilter.veiw_data));
    }
    // Only set when a hierarchy dropdown selection is active — the report
    // page falls back to the logged-in user's own name when this is absent.
    if (selectedUserName) {
      params.set('lead_user_name', selectedUserName);
    }

    window.open(`/dashboard/source-quality-report?${params.toString()}`, '_blank', 'noopener,noreferrer');
  };

  // Refetch whenever the tab, the local date range, or the dashboard-wide
  // filters (launch list above, drill-down selections) change. The launch
  // filter above the dashboard is picked up here via dashboardFilter.launch_id.
  useEffect(() => {
    const [start, end] = dateRange || [null, null];
    dispatch(
      fetchSourceQualityOverall({
        start_date: start ? start.format('YYYY-MM-DD') : undefined,
        end_date: end ? end.format('YYYY-MM-DD') : undefined,
      })
    );
  }, [
    sourceQualityOverallTab,
    dateRange,
    dashboardFilter.launch_id,
    dashboardFilter.lead_user_city_id,
    dashboardFilter.lead_user_id,
    dashboardFilter.lead_user_role_name,
    dashboardFilter?.veiw_data,
  ]);

  // Render the bar chart: sources on X axis, count for the active tab on Y axis.
  useEffect(() => {
    if (!refContainer.current) {
      return;
    }
    const categories = sourceQualityOverallData.map((item) => capitalize(item.source || ''));
    const seriesData = sourceQualityOverallData.map((item) => item.count);
    const seriesTotal = seriesData.reduce((sum, value) => sum + (value || 0), 0);

    const chart = Highcharts.chart(refContainer.current, {
      chart: {
        type: 'column',
      },
      title: {
        text: '',
      },
      subtitle: {
        text: '',
      },
      xAxis: {
        categories,
        crosshair: true,
        title: {
          text: 'Source',
        },
      },
      yAxis: {
        min: 0,
        title: {
          text: TAB_LABELS[sourceQualityOverallTab] || 'Count',
        },
      },
      credits: {
        enabled: false,
      },
      legend: {
        enabled: false,
      },
      plotOptions: {
        column: {
          dataLabels: {
            enabled: true,
            formatter: function (this: Highcharts.PointLabelObject) {
              const value = this.y || 0;
              const percentage = seriesTotal > 0 ? (value / seriesTotal) * 100 : 0;
              return `${percentage.toFixed(1)}%`;
            },
            style: {
              fontWeight: '600',
            },
          },
        },
      },
      series: [
        {
          type: 'column',
          name: TAB_LABELS[sourceQualityOverallTab] || 'Count',
          data: seriesData,
          pointWidth: 30,
          color: PRIMARY_COLOR,
        },
      ],
      responsive: {
        rules: [
          {
            condition: {
              maxWidth: 800,
            },
            chartOptions: {
              series: [
                {
                  type: 'column',
                  pointWidth: 15,
                },
              ],
            },
          },
        ],
      },
    });

    if (seriesData.length > 0) {
      chart.hideLoading();
    } else {
      chart.showLoading('No data available');
    }
  }, [sourceQualityOverallData, sourceQualityOverallTab]);

  const items: TabsProps['items'] = (['visited', 'token', 'booked'] as const).map((key) => ({
    key,
    label: TAB_LABELS[key],
  }));

  const totalCount = sourceQualityOverallData.reduce((sum, item) => sum + (item.count || 0), 0);

  return (
    <Row gutter={[40, 40]} className="mb-5">
      <Col span={24}>
        <div
          className="dashboard-section-header"
          style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}
        >
          <Title level={4}>Source Quality Overall</Title>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <RangePicker
              value={dateRange}
              onChange={(dates) => handleDateChange(dates as [Dayjs | null, Dayjs | null] | null)}
              disabledDate={disabledDate}
              allowClear
            />
            <Button
              icon={<FilePdfOutlined />}
              onClick={handleOpenReport}
              disabled={!sourceQualityOverallData.length}
            >
              Print Report
            </Button>
          </div>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}>
          <Tabs
            activeKey={sourceQualityOverallTab}
            size="middle"
            items={items}
            onChange={handleTabChange}
            className="custom-tabs-horizontal custom-tabs-no-content"
          />
          <Statistic
            title={
              <Text strong style={{ color: PRIMARY_COLOR, fontSize: 18 }}>
                Total {TAB_LABELS[sourceQualityOverallTab] || 'Count'}
              </Text>
            }
            value={totalCount}
            valueStyle={{ color: PRIMARY_COLOR, fontWeight: 700, fontSize: 22 }}
          />
        </div>
        <Spin spinning={sourceQualityOverallStatus === 'loading'}>
          {!sourceQualityOverallData.length && sourceQualityOverallStatus !== 'loading' ? (
            <Text type="secondary">No data available for the selected filters.</Text>
          ) : null}
          <div className="dashboard-graph-container">
            <div ref={refContainer} />
          </div>
        </Spin>
      </Col>
    </Row>
  );
};

export default SourceQualityOverall;
