import React, { useMemo, useState } from 'react';
import toast from 'react-hot-toast';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useLocale } from '@/app/providers/LocaleProvider';
import { AppLayout } from '@/shared/components/layout/AppLayout';
import { ContentPanel } from '@/shared/components/layout/ContentPanel';
import { Button } from '@/shared/components/ui';
import { ProjectsPageChrome } from '@/features/projects/components/ProjectsPageChrome';
import { ProjectsScopeFilter } from '@/features/projects/components/ProjectsScopeFilter';
import { PortfolioInsightsMenu } from '@/features/projects/components/PortfolioInsightsMenu';
import { PanelError } from '@/shared/components/ui/PageState';
import { ProjectCard } from '@/features/projects/components/ProjectCard';
import { ProjectsListSkeleton } from '@/features/projects/components/ProjectsListSkeleton';
import { ProjectsCardGrid } from '@/features/projects/components/projectsLayout';
import { useProjects, projectsQueryKey } from '@/features/projects/hooks/useProjects';
import { CreateProjectModal } from '@/features/projects/components/CreateProjectModal';
import { EmptyStateCard } from '@/features/onboarding/components/EmptyStateCard';
import { appEnv } from '@/shared/config/env';
import { archiveProject } from '@/features/projects/services/projectService';
import type { ProjectListFilters, ProjectListScope } from '@/features/projects/types/project.types';
import {
  extractApiErrorMessage,
  isAxiosErrorWithResponse,
} from '@/shared/utils/apiErrors';

function scopeToFilters(scope: ProjectListScope): ProjectListFilters {
  const base: ProjectListFilters = { per_page: 24, scope };
  if (scope === 'archived') {
    return { ...base, status: 'archived', include_archived: true };
  }
  return base;
}

function getErrorStatus(error: unknown): number | undefined {
  if (isAxiosErrorWithResponse(error)) {
    return error.response.status;
  }
  return undefined;
}

function getErrorMessage(error: unknown, fallback: string): string {
  if (isAxiosErrorWithResponse(error)) {
    return extractApiErrorMessage(error.response.data, fallback) ?? fallback;
  }
  if (error instanceof Error && error.message !== '') {
    return error.message;
  }
  return fallback;
}

const ProjectsPage: React.FC = () => {
  const { t } = useLocale();
  const queryClient = useQueryClient();
  const [showCreate, setShowCreate] = useState(false);
  const [scope, setScope] = useState<ProjectListScope>('active');
  const filters = useMemo(() => scopeToFilters(scope), [scope]);
  const { data, isLoading, isError, error, isFetching, refetch } = useProjects(filters);

  const archiveMutation = useMutation({
    mutationFn: (projectId: string) => archiveProject(projectId),
    onSuccess: () => {
      toast.success(t('projects:lifecycle.archiveSuccess'));
      void queryClient.invalidateQueries({ queryKey: projectsQueryKey(filters) });
    },
    onError: () => toast.error(t('projects:lifecycle.archiveFailed')),
  });

  const projects = data?.data ?? [];

  const errorStatus = useMemo(() => (isError ? getErrorStatus(error) : undefined), [error, isError]);
  const isForbidden = errorStatus === 403;
  const errorMessage = useMemo(
    () => (isError ? getErrorMessage(error, t('projects:states.error')) : ''),
    [error, isError, t],
  );

  const body = (() => {
    if (isLoading) {
      return <ProjectsListSkeleton />;
    }

    if (isError && isForbidden) {
      return (
        <ContentPanel role="alert" variant="muted" padding="lg">
          <p>{t('projects:states.forbidden')}</p>
        </ContentPanel>
      );
    }

    if (isError) {
      return (
        <>
          <PanelError
            message={errorMessage}
            retryLabel={t('projects:states.retry')}
            onRetry={() => refetch()}
            loading={isFetching}
          />
          {!appEnv.isProduction && error instanceof Error && error.stack && (
            <ContentPanel variant="inset" padding="md" style={{ marginTop: '1rem' }}>
              <pre style={{ margin: 0, fontSize: '0.75rem', overflow: 'auto' }}>{error.stack}</pre>
            </ContentPanel>
          )}
        </>
      );
    }

    if (projects.length === 0) {
      return (
        <EmptyStateCard
          icon="📁"
          title={t('projects:states.empty.title')}
          description={t('projects:states.empty.description')}
          actionLabel={scope === 'active' ? t('projects:states.empty.action') : undefined}
          onAction={scope === 'active' ? () => setShowCreate(true) : undefined}
        />
      );
    }

    return (
      <ProjectsCardGrid data-testid="projects-grid">
        {projects.map((project) => (
          <ProjectCard
            key={project.id}
            project={project}
            onArchive={
              project.permissions?.can_manage && project.status !== 'archived'
                ? () => archiveMutation.mutate(project.id)
                : undefined
            }
          />
        ))}
      </ProjectsCardGrid>
    );
  })();

  return (
    <AppLayout>
      <ProjectsPageChrome
        title={t('projects:title')}
        actions={
          <>
            <PortfolioInsightsMenu />
            <Button type="button" onClick={() => setShowCreate(true)} data-testid="projects-create-button">
              {t('projects:create')}
            </Button>
          </>
        }
        scopeNav={<ProjectsScopeFilter scope={scope} onChange={setScope} />}
      />
      {body}
      {showCreate && (
        <CreateProjectModal
          onClose={() => setShowCreate(false)}
          onCreated={() => {
            setShowCreate(false);
            void refetch();
          }}
        />
      )}
    </AppLayout>
  );
};

export default ProjectsPage;
