import { useState, useEffect } from 'react';
import {
  getNotifications,
  getReadNotifications,
} from '../../api/Notifications';
import {
  getRequests,
  Request,
  RequestTableData,
  transformRequests,
} from '../../api/Requests';
import { useAuth } from '../../auth/AuthProvider';
import ContentCard from '../shared/ContentCard';
import { Link } from 'react-router-dom';
import { ResponsiveContainer } from 'recharts';
import ChartDropdown from '../charts/ChartDropdown';
import SupplierRequestChart from '../charts/HorizontalBarChart';
import SummaryMetrics from './SummaryMetrics';

export default function StudentDashboard() {
  const { user } = useAuth();
  const [incomingRequests, setIncomingRequests] = useState<RequestTableData[]>(
    []
  );
  const [teamRequests, setTeamRequests] = useState<Request[]>([]);
  const [incomingRequestSupplierData, setIncomingRequestSupplierData] =
    useState<{ name: string; count: number }[]>([]);
  const [allRequestConfigurableData, setAllRequestConfigurableData] = useState<
    { name: string; count: number }[]
  >([]);
  const [oldestRequestAge, setOldestRequestAge] = useState<string>('');
  const [unreadCount, setUnreadCount] = useState<number>(0);
  const [metricsData, setMetricsData] = useState<[string, string][]>([]);
  const [selectedKey, setSelectedKey] = useState<keyof Request>('status');

  const getAndSetOldestIncomingRequestAge = (
    transformedIncomingRequests: RequestTableData[]
  ) => {
    if (transformedIncomingRequests.length === 0) return null;

    const oldestRequest = transformedIncomingRequests.reduce(
      (oldest, current) =>
        new Date(oldest.request_timestamp as string) <
        new Date(current.request_timestamp as string)
          ? oldest
          : current
    );

    const currentTime = new Date();
    const oldestRequestTime = new Date(
      oldestRequest.request_timestamp as string
    );

    const timeDifference = currentTime.getTime() - oldestRequestTime.getTime();
    const totalDays = timeDifference / (1000 * 3600 * 24);

    const days = Math.floor(totalDays);
    const hours = Math.round((totalDays - days) * 24);

    const formattedAge = `${days} day${days !== 1 ? 's' : ''}${
      hours > 0 ? `, ${hours} hour${hours !== 1 ? 's' : ''}` : ''
    } ago`;

    setOldestRequestAge(formattedAge);
  };

  function getChartData<T>(
    data: T[],
    category: keyof T
  ): { name: string; count: number }[] {
    const counts: Record<string, number> = {};

    data.forEach((item) => {
      const key = item[category];
      if (key != null) {
        const keyStr = String(key);
        counts[keyStr] = (counts[keyStr] || 0) + 1;
      }
    });

    return Object.entries(counts).map(([name, count]) => ({ name, count }));
  }

  const retrieveBaseData = async () => {
    if (!teamRequests.length) {
      return;
    }

    const incomingRequests = teamRequests.filter(
      (request) => !['delivered', 'cancelled'].includes(request.status)
    );

    const transformed = await transformRequests(incomingRequests);
    setIncomingRequests(transformed);

    const supplierCounts = transformed.reduce(
      (acc, req) => {
        if (req.supplier_id != null) {
          acc[req.supplier_id as number] =
            (acc[req.supplier_id as number] || 0) + 1;
        }
        return acc;
      },
      {} as Record<number, number>
    );

    const incomingRequestSupplierResult = Object.entries(supplierCounts).map(
      ([supplierId, count]) => ({
        name: `${supplierId}`,
        count,
      })
    );
    setIncomingRequestSupplierData(incomingRequestSupplierResult);

    getAndSetOldestIncomingRequestAge(transformed);

    // ***** GET METRICS DATA below ***** //
    const totalRequested = teamRequests
      .reduce((sum, request) => sum + (request.subtotal || 0), 0)
      .toFixed(2);

    const transformedTeamRequests = await transformRequests(teamRequests);

    const supplierCount: { [key: string]: number } = {};
    transformedTeamRequests.forEach((request) => {
      const supplier = request.supplier_id;
      supplierCount[supplier] = (supplierCount[supplier] || 0) + 1;
    });
    let topSupplier = '';
    let maxRequests = 0;
    for (const supplier in supplierCount) {
      if (supplierCount[supplier] > maxRequests) {
        topSupplier = supplier;
        maxRequests = supplierCount[supplier];
      }
    }

    const deliveredRequests = teamRequests.filter((request) =>
      ['delivered'].includes(request.status)
    );

    const newMetrics: [string, string][] = [
      ['# of Requests', teamRequests.length.toString()],
      ['# of Delivered Requests', deliveredRequests.length.toString()],
      [
        'Total Requested',
        new Intl.NumberFormat('en-US', {
          style: 'currency',
          currency: 'USD',
        }).format(Number(totalRequested)),
      ],
      // Add more metrics here as needed
    ];

    setMetricsData(newMetrics);
    // ***** GET METRICS DATA above ***** //
  };

  const setTeamRequestsChart = (yaxis: string) => {
    const allRequestConfigurableResult = getChartData(
      teamRequests,
      yaxis as keyof Request
    );
    setAllRequestConfigurableData(allRequestConfigurableResult);
  };

  useEffect(() => {
    const getAndSetNotifications = async () => {
      let notis;
      try {
        notis = await getNotifications(user?.team_id);
      } catch (error) {
        console.error(error);
        return;
      }

      const readResult = await getReadNotifications(user?.user_id as number);
      const unreadCount = notis.filter(
        (notification) =>
          !readResult.some(
            (read) => read.notification_id === notification.notification_id
          )
      ).length;
      setUnreadCount(unreadCount);
    };

    const getAndSetTeamRequests = async () => {
      const result = await getRequests(undefined, user?.team_id);
      setTeamRequests(result);
    };

    getAndSetNotifications();
    getAndSetTeamRequests();
  }, []);

  useEffect(() => {
    setTeamRequestsChart('status');
    retrieveBaseData();
  }, [teamRequests]);

  return (
    <>
      <div className='row'>
        <div className='col-md-6 mb-3'>
          <div className='mb-3'>
            <ContentCard
              title='Unread Notifications'
              description='You will receive a notification each time a request is updated or created.'
            >
              <div>
                You have{' '}
                <strong>
                  {' '}
                  {unreadCount} unread notification
                  {unreadCount !== 1 && 's'}
                </strong>
                .{' '}
                <Link to='/notifications'>
                  Click here to view all notifications.
                </Link>
              </div>
            </ContentCard>
          </div>
          <ContentCard
            title='Pending Requests'
            description='Pending requests are any requests not marked as delivered or cancelled.'
          >
            {incomingRequests.length == 0 && (
              <div>
                Your team has <strong>no pending requests</strong>
                {'. '}
                <Link to='/student/requests'>
                  Click here to view your team's requests.
                </Link>
              </div>
            )}

            {incomingRequests.length > 0 && (
              <>
                <div>
                  Your team has{' '}
                  <strong>
                    {incomingRequests.length} pending request
                    {incomingRequests.length !== 1 && 's'}{' '}
                  </strong>{' '}
                  that {incomingRequests.length === 1 ? 'has' : 'have'} not yet
                  been delivered. The oldest pending request was made{' '}
                  <strong>{oldestRequestAge}</strong>.{' '}
                  <Link to='/student/requests'>
                    Click here to view your team's requests.
                  </Link>
                </div>
                <hr />
                <div
                  className='w-100'
                  style={{ height: '400px', marginBottom: '1rem' }}
                >
                  <h4 style={{ textAlign: 'center', marginTop: '20px' }}>
                    Pending Requests by Supplier
                  </h4>
                  <ResponsiveContainer width='100%' height='100%'>
                    <SupplierRequestChart
                      data={incomingRequestSupplierData}
                      xlabel={'Number of Requests'}
                      ylabel={'Supplier'}
                    />
                  </ResponsiveContainer>
                </div>
              </>
            )}
          </ContentCard>
        </div>
        <div className='col-md-6'>
          <ContentCard title='Team Summary Metrics'>
            {metricsData.length ? (
              <>
                <SummaryMetrics metrics={metricsData} />
                <hr />
                <div
                  className='w-100'
                  style={{ height: '650px', marginBottom: '1rem' }}
                >
                  <div className='d-flex justify-content-center align-items-center my-3 gap-3'>
                    <h4 className='mb-0'>Your Team's Requests by</h4>
                    <ChartDropdown
                      selectedKey={selectedKey}
                      setSelectedKey={setSelectedKey}
                      setAllRequestsChart={setTeamRequestsChart}
                    />
                  </div>
                  <ResponsiveContainer width='100%' height='100%'>
                    <SupplierRequestChart
                      data={allRequestConfigurableData}
                      xlabel={'Number of Requests'}
                      ylabel={selectedKey}
                    />
                  </ResponsiveContainer>
                </div>
              </>
            ) : (
              <div className='d-flex justify-content-center align-items-center'>
                There are no metrics to display.
              </div>
            )}
          </ContentCard>
        </div>
      </div>
    </>
  );
}
