import React, { useMemo, useState } from 'react';
import styled from 'styled-components';
import { useQuery } from '@tanstack/react-query';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { useLocale } from '@/app/providers/LocaleProvider';
import { useAuthStore } from '@/features/auth/store/authStore';
import { AppLayout } from '@/shared/components/layout/AppLayout';
import { ContentPanel } from '@/shared/components/layout/ContentPanel';
import { PageHeader } from '@/shared/components/layout/PageHeader';
import { Button, Card, Select, Spinner } from '@/shared/components/ui';
import {
  SEARCH_SORT_OPTIONS,
  getSearchSortParams,
  parseSearchSortKey,
} from '@/features/search/utils/searchSort';
import { ROUTES } from '@/shared/constants/routes';
import { TicketListCard } from '@/features/tickets/components/TicketListCard';
import { useTickets } from '@/features/tickets/hooks/useTickets';
import { useTicketFilterOptions } from '@/features/tickets/hooks/useTicketFilterOptions';
import { useTicketFormOptions } from '@/features/tickets/hooks/useTicketFormOptions';
import { SearchFiltersPanel } from '@/features/search/components/SearchFiltersPanel';
import { SearchHero } from '@/features/search/components/SearchHero';
import { ActiveFilterChips } from '@/features/search/components/ActiveFilterChips';
import { SearchSuggestionsList } from '@/features/search/components/SearchSuggestionsList';
import { SavedFiltersBar } from '@/features/search/components/SavedFiltersBar';
import { useSearchTickets } from '@/features/search/hooks/useSearchTickets';
import { useSearchSuggestions } from '@/features/search/hooks/useSearchSuggestions';
import { useSavedFilters } from '@/features/search/hooks/useSavedFilters';
import { useSavedFilterMutations } from '@/features/search/hooks/useSavedFilterMutations';
import {
  applySavedFilter,
  fetchQuickFilterTickets,
} from '@/features/search/services/searchService';
import type { QuickFilter, SearchFilters, SearchRequest } from '@/features/search/types/search.types';
import { buildSearchFiltersPayload } from '@/features/search/types/search.types';

const SearchWorkspace = styled.div`
  display: grid;
  grid-template-columns: minmax(11.5rem, 13.75rem) minmax(0, 1fr);
  gap: ${({ theme }) => theme.layout.cardGap};
  align-items: start;
  margin-bottom: ${({ theme }) => theme.layout.cardGap};

  @media (max-width: 900px) {
    grid-template-columns: 1fr;
  }
`;

const FiltersAside = styled.aside`
  position: sticky;
  top: calc(${({ theme }) => theme.layout.headerHeight} + ${({ theme }) => theme.spacing[4]});
  padding: ${({ theme }) => theme.spacing[4]};
  border-radius: ${({ theme }) => theme.borderRadius.md};
  background: ${({ theme }) => theme.colors.surfaceInset};
  border: 1px solid ${({ theme }) => theme.colors.borderSoft};

  @media (max-width: 900px) {
    position: static;
  }
`;

const SearchMain = styled.div`
  display: flex;
  flex-direction: column;
  gap: ${({ theme }) => theme.spacing[5]};
  min-width: 0;
`;

const SearchPanel = styled(ContentPanel)`
  margin-bottom: 0;
`;

const SearchForm = styled.form`
  display: none;
`;

const ResultsSection = styled.section`
  display: flex;
  flex-direction: column;
  gap: ${({ theme }) => theme.spacing[4]};
`;

const ResultsToolbar = styled.div`
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: ${({ theme }) => theme.layout.toolbarGap};
  padding: ${({ theme }) => `${theme.spacing[3]} ${theme.spacing[4]}`};
  border-radius: ${({ theme }) => theme.borderRadius.xl};
  background: ${({ theme }) => theme.colors.surfaceInset};
  border: 1px solid ${({ theme }) => theme.colors.borderSoft};
`;

const Meta = styled.div`
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};
  color: ${({ theme }) => theme.colors.text.primary};
  text-align: start;
`;

const SortControl = styled.div`
  min-width: 12rem;
  flex: 1 1 12rem;
  max-width: 16rem;
`;

const Results = styled.div`
  display: flex;
  flex-direction: column;
  gap: ${({ theme }) => theme.spacing[3]};
`;

const Centered = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: ${({ theme }) => theme.spacing[4]};
  padding: ${({ theme }) => theme.spacing[12]} ${({ theme }) => theme.spacing[4]};
  text-align: center;
  color: ${({ theme }) => theme.colors.text.secondary};
`;

const PaginationBar = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: ${({ theme }) => theme.layout.toolbarGap};
  margin-top: ${({ theme }) => theme.layout.dashboardStatGap};
  padding-top: ${({ theme }) => theme.spacing[4]};
  border-top: 1px solid ${({ theme }) => theme.colors.borderSoft};
`;

type SearchMode = 'search' | 'quick' | 'saved';

const DEFAULT_FILTERS: SearchFilters = {};

const SearchPage: React.FC = () => {
  const { t } = useLocale();
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const user = useAuthStore((state) => state.user);
  const departmentId = user?.is_super_admin ? undefined : user?.departments[0]?.id;

  const [query, setQuery] = useState('');
  const [filters, setFilters] = useState<SearchFilters>(DEFAULT_FILTERS);
  const [page, setPage] = useState(1);
  const [mode, setMode] = useState<SearchMode>('search');
  const [activeQuickId, setActiveQuickId] = useState<string | null>(null);
  const [activeSavedId, setActiveSavedId] = useState<string | null>(null);
  const [submitted, setSubmitted] = useState(true);

  const perPage = 25;
  const sortKey = parseSearchSortKey(searchParams.get('sort'));
  const { sort_by: sortBy, sort_direction: sortDirection } = getSearchSortParams(sortKey);

  const searchRequest: SearchRequest = useMemo(
    () => ({
      query: query.trim() || undefined,
      filters,
      page,
      per_page: perPage,
      department_id: departmentId,
      sort_by: sortBy,
      sort_direction: sortDirection,
    }),
    [query, filters, page, departmentId, sortBy, sortDirection],
  );

  const handleSortChange = (value: string) => {
    const nextKey = parseSearchSortKey(value);
    setSearchParams(
      (current) => {
        const params = new URLSearchParams(current);
        params.set('sort', nextKey);
        return params;
      },
      { replace: true },
    );
    setMode('search');
    setActiveQuickId(null);
    setActiveSavedId(null);
    setPage(1);
    setSubmitted(true);
  };

  const searchQuery = useSearchTickets(searchRequest, mode === 'search');
  const suggestionsQuery = useSearchSuggestions();
  const savedFiltersQuery = useSavedFilters();
  const filterMutations = useSavedFilterMutations();

  const optionSeed = useTickets({ page: 1, per_page: 100 });
  const { statuses, priorities } = useTicketFilterOptions(optionSeed.data?.data ?? []);
  const formOptionsQuery = useTicketFormOptions(departmentId);
  const categories = formOptionsQuery.data?.categories ?? [];

  const quickQuery = useQuery({
    queryKey: ['search', 'quick', activeQuickId, page, perPage],
    queryFn: () => fetchQuickFilterTickets(activeQuickId!, perPage, page),
    enabled: mode === 'quick' && Boolean(activeQuickId),
  });

  const savedApplyQuery = useQuery({
    queryKey: ['search', 'saved-apply', activeSavedId, page, perPage],
    queryFn: () => applySavedFilter(activeSavedId!, perPage, page),
    enabled: mode === 'saved' && Boolean(activeSavedId),
  });

  const activeResult =
    mode === 'quick'
      ? quickQuery
      : mode === 'saved'
        ? savedApplyQuery
        : searchQuery;

  const tickets = activeResult.data?.tickets ?? [];
  const totalCount = activeResult.data?.total_count ?? 0;
  const searchMs = activeResult.data?.search_time_ms ?? null;
  const totalPages = activeResult.data?.pagination.total_pages ?? 1;

  const handleSearch = (event?: React.FormEvent) => {
    event?.preventDefault();
    setMode('search');
    setActiveQuickId(null);
    setActiveSavedId(null);
    setPage(1);
    setSubmitted(true);
  };

  const handleQuickSelect = (quick: QuickFilter) => {
    const quickEndpoints = ['my-tickets', 'unassigned', 'overdue', 'high-priority'];
    setSubmitted(true);
    setPage(1);
    setActiveSavedId(null);

    if (quickEndpoints.includes(quick.id)) {
      setMode('quick');
      setActiveQuickId(quick.id);
      return;
    }

    setMode('search');
    setActiveQuickId(null);
    const data = (quick.filter_data ?? {}) as SearchFilters;
    setFilters({
      ...filters,
      sla_status: typeof data.sla_status === 'string' ? data.sla_status : filters.sla_status,
      is_unassigned:
        typeof data.is_unassigned === 'boolean' ? data.is_unassigned : filters.is_unassigned,
      is_replied: typeof data.is_replied === 'boolean' ? data.is_replied : filters.is_replied,
      date_from: typeof data.date_from === 'string' ? data.date_from : filters.date_from,
    });
  };

  const handleSavedSelect = (filterId: string) => {
    setMode('saved');
    setActiveSavedId(filterId);
    setActiveQuickId(null);
    setPage(1);
    setSubmitted(true);
  };

  const handleSaveCurrent = async (name: string) => {
    await filterMutations.createMutation.mutateAsync({
      name,
      filter_data: {
        ...buildSearchFiltersPayload(filters),
        ...(query.trim() ? { query: query.trim() } : {}),
      },
    });
  };

  return (
    <AppLayout>
      <PageHeader title={t('search:title')} />

      <SearchWorkspace>
        <FiltersAside>
          <SavedFiltersBar
            variant="rail"
            personal={savedFiltersQuery.data?.personal ?? []}
            shared={savedFiltersQuery.data?.shared ?? []}
            quick={savedFiltersQuery.data?.quick ?? []}
            activeQuickId={activeQuickId}
            activeSavedId={activeSavedId}
            isLoading={savedFiltersQuery.isLoading}
            isError={savedFiltersQuery.isError}
            isSaving={filterMutations.createMutation.isPending}
            onQuickSelect={handleQuickSelect}
            onSavedSelect={(filter) => handleSavedSelect(filter.id)}
            onSaveCurrent={(name) => void handleSaveCurrent(name)}
            onDeleteSaved={(id) => filterMutations.deleteMutation.mutate(id)}
          />
        </FiltersAside>

        <SearchMain>
          <SearchPanel variant="elevated" padding="md">
            <SearchHero
              query={query}
              loading={activeResult.isFetching}
              onQueryChange={setQuery}
              onSubmit={handleSearch}
            />

            <ActiveFilterChips
              filters={filters}
              query={query}
              statuses={statuses}
              priorities={priorities}
              categories={categories}
              onRemove={(patch) => {
                setFilters((current) => ({ ...current, ...patch }));
                setMode('search');
                setActiveQuickId(null);
                setActiveSavedId(null);
              }}
              onClearQuery={() => setQuery('')}
            />

            <SearchForm onSubmit={handleSearch} aria-hidden />

            <SearchSuggestionsList
              suggestions={suggestionsQuery.data ?? []}
              isLoading={suggestionsQuery.isLoading}
              isError={suggestionsQuery.isError}
              onSelect={(value) => {
                setQuery(value);
                handleSearch();
              }}
            />

            <SearchFiltersPanel
              filters={filters}
              statuses={statuses}
              priorities={priorities}
              categories={categories}
              departmentId={departmentId}
              onChange={(patch) => {
                setFilters((current) => ({ ...current, ...patch }));
                setMode('search');
                setActiveQuickId(null);
                setActiveSavedId(null);
              }}
            />
          </SearchPanel>

          <ResultsSection>
      {submitted &&
        !activeResult.isLoading &&
        !activeResult.isError &&
        (totalCount > 0 || mode === 'search') && (
        <ResultsToolbar>
          <Meta>
            {totalCount > 0
              ? t('search:results.summary', {
                  count: totalCount,
                  ms: searchMs !== null ? Math.round(searchMs) : '—',
                })
              : t('search:states.empty')}
          </Meta>
          {mode === 'search' ? (
            <SortControl>
              <Select
                data-testid="search-sort"
                label={t('search:sort.label')}
                value={sortKey}
                onChange={(event) => handleSortChange(event.target.value)}
                options={SEARCH_SORT_OPTIONS.map((option) => ({
                  value: option.key,
                  label: t(option.labelKey),
                }))}
              />
            </SortControl>
          ) : null}
        </ResultsToolbar>
      )}

      {activeResult.isLoading && tickets.length === 0 && (
        <Centered role="status">
          <Spinner size="lg" />
          <p>{t('search:states.loading')}</p>
        </Centered>
      )}

      {activeResult.isError && (
        <Centered role="alert">
          <p>{t('search:states.error')}</p>
          <Button variant="primary" onClick={() => activeResult.refetch()}>
            {t('search:states.retry')}
          </Button>
        </Centered>
      )}

      {!activeResult.isLoading && !activeResult.isError && submitted && tickets.length === 0 && (
        <Card variant="elevated" padding="lg">
          <p style={{ margin: 0, color: 'var(--text-secondary)' }}>{t('search:states.empty')}</p>
        </Card>
      )}

      <Results>
        {tickets.map((ticket) => (
          <TicketListCard
            key={ticket.id}
            ticket={ticket}
            onClick={() => navigate(ROUTES.TICKET_DETAIL(ticket.id))}
          />
        ))}
      </Results>

      {tickets.length > 0 && totalPages > 1 && (
        <PaginationBar>
          <Button
            variant="outline"
            disabled={page <= 1}
            onClick={() => setPage((current) => Math.max(1, current - 1))}
          >
            {t('search:pagination.previous')}
          </Button>
          <span>
            {t('search:pagination.summary', { page, totalPages, total: totalCount })}
          </span>
          <Button
            variant="outline"
            disabled={page >= totalPages}
            onClick={() => setPage((current) => current + 1)}
          >
            {t('search:pagination.next')}
          </Button>
        </PaginationBar>
      )}
          </ResultsSection>
        </SearchMain>
      </SearchWorkspace>
    </AppLayout>
  );
};

export default SearchPage;
