import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { AppLayout } from '@/shared/components/layout/AppLayout';
import { ProjectsPageChrome } from '@/features/projects/components/ProjectsPageChrome';
import { Button } from '@/shared/components/ui';
import { PageSection } from '@/shared/components/layout/PageSection';
import { PanelLoadingState } from '@/shared/components/ui/PageState';
import { useLocale } from '@/app/providers/LocaleProvider';
import { ProjectsAreaSubnav } from '@/features/projects/components/ProjectsAreaSubnav';
import { InlineActions } from '@/features/projects/components/projectsLayout';
import { PortfolioViewToggle, type PortfolioTimelineView } from '@/features/projects/components/PortfolioViewToggle';
import { PortfolioExecutiveGantt } from '@/features/projects/components/PortfolioExecutiveGantt';
import { PortfolioExecutiveTimeline } from '@/features/projects/components/PortfolioExecutiveTimeline';
import { PortfolioDetailedGantt } from '@/features/projects/components/PortfolioDetailedGantt';
import {
  PortfolioFiltersBar,
  type PortfolioClientFilters,
  type PortfolioProjectFilter,
} from '@/features/projects/components/PortfolioFiltersBar';
import { CreateProjectModal } from '@/features/projects/components/CreateProjectModal';
import { usePortfolioGantt } from '@/features/projects/hooks/useProjectGantt';
import { ROUTES } from '@/shared/constants/routes';
import { trackProductEvent } from '@/shared/analytics/productAnalytics';

function parseViewParam(value: string | null): PortfolioTimelineView {
  if (value === 'gantt') return 'gantt';
  if (value === 'timeline') return 'timeline';
  return 'executive';
}

function parseFilterParam(value: string | null): PortfolioProjectFilter {
  if (
    value === 'active' ||
    value === 'at_risk' ||
    value === 'delayed' ||
    value === 'blocked' ||
    value === 'completed'
  ) {
    return value;
  }
  return 'all';
}

function viewAnalyticsEvent(view: PortfolioTimelineView) {
  if (view === 'gantt') return 'detailed_gantt_view_opened' as const;
  if (view === 'timeline') return 'timeline_view_opened' as const;
  return 'executive_gantt_opened' as const;
}

const DEFAULT_CLIENT_FILTERS: PortfolioClientFilters = {
  departmentId: null,
  health: 'all',
  ownerUserIds: [],
  search: '',
};

const PortfolioTimelinePage: React.FC = () => {
  const { t } = useLocale();
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const view = parseViewParam(searchParams.get('view'));
  const portfolioFilter = parseFilterParam(searchParams.get('filter'));
  const initialViewTracked = useRef(false);
  const portfolioOpenedTracked = useRef(false);

  const [range, setRange] = useState<'year' | 'quarter' | 'month'>('year');
  const [showCreate, setShowCreate] = useState(false);
  const [clientFilters, setClientFilters] = useState<PortfolioClientFilters>(DEFAULT_CLIENT_FILTERS);
  const year = new Date().getFullYear();
  const month = new Date().getMonth() + 1;

  const { data, isLoading, isError } = usePortfolioGantt({
    range,
    year,
    quarter: range === 'quarter' ? Math.ceil(month / 3) : undefined,
    month: range === 'month' ? month : undefined,
    active_only: portfolioFilter === 'active',
    delayed_only: portfolioFilter === 'delayed',
    blocked_only: portfolioFilter === 'blocked',
    at_risk_only: portfolioFilter === 'at_risk',
    status: portfolioFilter === 'completed' ? 'completed' : undefined,
    department_id: clientFilters.departmentId ?? undefined,
    owner_user_ids:
      clientFilters.ownerUserIds.length > 0 ? clientFilters.ownerUserIds : undefined,
    health_filter:
      clientFilters.health !== 'all' ? clientFilters.health : undefined,
    search: clientFilters.search.trim() || undefined,
  });

  const rangeStart = data?.range_start
    ? new Date(data.range_start)
    : range === 'month'
      ? new Date(year, month - 1, 1)
      : range === 'quarter'
        ? new Date(year, Math.floor((month - 1) / 3) * 3, 1)
        : new Date(year, 0, 1);
  const rangeEnd = data?.range_end
    ? new Date(data.range_end)
    : range === 'month'
      ? new Date(year, month, 0)
      : range === 'quarter'
        ? new Date(year, Math.floor((month - 1) / 3) * 3 + 3, 0)
        : new Date(year, 11, 31);

  const filterOptions = useMemo(
    () => ({
      departments: data?.filter_options?.departments ?? [],
      owners: data?.filter_options?.owners ?? [],
    }),
    [data?.filter_options],
  );

  useEffect(() => {
    if (portfolioOpenedTracked.current) return;
    portfolioOpenedTracked.current = true;
    trackProductEvent('portfolio_view_opened');
  }, []);

  useEffect(() => {
    if (initialViewTracked.current) return;
    initialViewTracked.current = true;
    trackProductEvent(viewAnalyticsEvent(view));
  }, [view]);

  const handleViewChange = useCallback(
    (next: PortfolioTimelineView) => {
      if (next === view) return;

      trackProductEvent('portfolio_view_switched', { from: view, to: next });

      const params = new URLSearchParams(searchParams);
      if (next === 'executive') {
        params.delete('view');
      } else {
        params.set('view', next);
      }
      setSearchParams(params, { replace: true });
      trackProductEvent(viewAnalyticsEvent(next));
    },
    [searchParams, setSearchParams, view],
  );

  const handleFilterChange = useCallback(
    (next: PortfolioProjectFilter) => {
      const params = new URLSearchParams(searchParams);
      if (next === 'all') {
        params.delete('filter');
      } else {
        params.set('filter', next);
      }
      setSearchParams(params, { replace: true });
      trackProductEvent('portfolio_filter_applied', { filter: next, type: 'project' });
    },
    [searchParams, setSearchParams],
  );

  const handleClientFiltersChange = useCallback((next: PortfolioClientFilters) => {
    setClientFilters(next);
    trackProductEvent('portfolio_filter_applied', {
      type: 'client',
      department_id: next.departmentId ?? 'all',
      health: next.health,
      owners: next.ownerUserIds.length,
      search: next.search ? 1 : 0,
    });
  }, []);

  const openDetailedGanttForProject = useCallback(
    (projectId: string) => {
      trackProductEvent('project_row_opened', { view: 'executive_detailed', project_id: projectId });
      handleViewChange('gantt');
    },
    [handleViewChange],
  );

  const sectionTitle =
    view === 'gantt'
      ? t('projects:portfolioTimeline.detailedGanttTitle')
      : view === 'timeline'
        ? t('projects:portfolioTimeline.timelineOverviewTitle')
        : t('projects:portfolioTimeline.executiveGanttTitle');

  return (
    <AppLayout>
      <ProjectsPageChrome
        title={t('projects:portfolioNav.timeline')}
        subtitle={t('projects:portfolioNav.timelineSubtitle')}
        areaNav={<ProjectsAreaSubnav />}
      />
      <PageSection title={sectionTitle}>
        <InlineActions style={{ marginBottom: '1rem', flexWrap: 'wrap' }}>
          <PortfolioViewToggle value={view} onChange={handleViewChange} />
          <Button
            type="button"
            variant={range === 'year' ? 'primary' : 'secondary'}
            size="sm"
            onClick={() => setRange('year')}
          >
            {t('projects:gantt.range.year')}
          </Button>
          <Button
            type="button"
            variant={range === 'quarter' ? 'primary' : 'secondary'}
            size="sm"
            onClick={() => setRange('quarter')}
          >
            {t('projects:gantt.range.quarter')}
          </Button>
          <Button
            type="button"
            variant={range === 'month' ? 'primary' : 'secondary'}
            size="sm"
            onClick={() => setRange('month')}
          >
            {t('projects:gantt.range.month')}
          </Button>
          <Button type="button" variant="secondary" size="sm" onClick={() => navigate(ROUTES.PORTFOLIO)}>
            {t('projects:portfolio.link')}
          </Button>
        </InlineActions>

        {data && (
          <PortfolioFiltersBar
            projectFilter={portfolioFilter}
            clientFilters={clientFilters}
            departments={filterOptions.departments}
            owners={filterOptions.owners}
            onProjectFilterChange={handleFilterChange}
            onClientFiltersChange={handleClientFiltersChange}
          />
        )}

        {isLoading ? (
          <PanelLoadingState label={t('projects:states.loading')} />
        ) : isError ? (
          <p>{t('projects:errors.load')}</p>
        ) : data ? (
          view === 'executive' ? (
            <PortfolioExecutiveGantt
              rows={data.timeline}
              summary={data.summary}
              rangeStart={rangeStart}
              rangeEnd={rangeEnd}
              onOpenDetailedGantt={openDetailedGanttForProject}
              onCreateProject={() => setShowCreate(true)}
            />
          ) : view === 'timeline' ? (
            <PortfolioExecutiveTimeline
              rows={data.timeline}
              rangeStart={rangeStart}
              rangeEnd={rangeEnd}
              crossProjectDependencies={data.cross_project_dependencies}
              onCreateProject={() => setShowCreate(true)}
            />
          ) : (
            <PortfolioDetailedGantt
              rows={data.timeline}
              rangeStart={rangeStart}
              rangeEnd={rangeEnd}
              summary={data.summary}
            />
          )
        ) : null}
        {data && view !== 'timeline' && data.cross_project_dependencies.length > 0 && (
          <p style={{ marginTop: '1rem', fontSize: '0.875rem' }}>
            {t('projects:gantt.crossDepsHint', {
              count: data.cross_project_dependencies.length,
            })}{' '}
            <Button
              type="button"
              variant="secondary"
              size="sm"
              onClick={() => navigate(ROUTES.PORTFOLIO_DEPENDENCIES)}
            >
              {t('projects:portfolioNav.crossDependencies')}
            </Button>
          </p>
        )}
      </PageSection>
      {showCreate && (
        <CreateProjectModal onClose={() => setShowCreate(false)} onCreated={() => setShowCreate(false)} />
      )}
    </AppLayout>
  );
};

export default PortfolioTimelinePage;
export type { PortfolioProjectFilter };
