import React from 'react';
import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';
import InputAdornment from '@mui/material/InputAdornment';
import Autocomplete from '@mui/material/Autocomplete';
import FormControlLabel from '@mui/material/FormControlLabel';
import MenuItem from '@mui/material/MenuItem';
import Menu from '@mui/material/Menu';
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
import ToggleButton from '@mui/material/ToggleButton';
import SwapVertIcon from '@mui/icons-material/SwapVert';
import ViewListOutlinedIcon from '@mui/icons-material/ViewListOutlined';
import MapOutlinedIcon from '@mui/icons-material/MapOutlined';
import LocationOnOutlinedIcon from '@mui/icons-material/LocationOnOutlined';
import type { SxProps, Theme } from '@mui/material/styles';
import { WizardLayout } from '../../templates/WizardLayout';
import { VenueCard } from '../../molecules/VenueCard';
import { FilterPanel } from '../../molecules/FilterPanel';
import { Button } from '../../atoms/Button';
import { Chip } from '../../atoms/Chip';
import { Switch } from '../../atoms/Switch';
import { Typography } from '../../atoms/Typography';
import { Divider } from '../../atoms/Divider';

// ─── Types ───────────────────────────────────────────────────────────────────

/** A venue available for selection */
export interface Venue {
  id: string;
  name: string;
  imageUrl: string;
  location: string;
  capacity?: number;
  price?: number;
}

/** A venue type option for the filter */
export interface VenueTypeOption {
  /** Machine-readable value */
  value: string;
  /** Human-readable label */
  label: string;
}

/** Structured filter state for the venue list */
export interface VenueFilterValues {
  /** Selected venue type values (empty = all) */
  venueTypes: string[];
  /** Show only venues with video streaming */
  videoStreaming: boolean;
  /** Show only venues with photo display */
  photoDisplay: boolean;
  /** Selected service tradition (null = any) */
  tradition: string | null;
}

/** Sort options for the venue list */
export type VenueSortBy = 'recommended' | 'nearest' | 'price_low' | 'price_high';

/** View mode for the listing */
export type ListViewMode = 'list' | 'map';

/** Props for the VenueStep page component */
export interface VenueStepProps {
  /** List of venues to display */
  venues: Venue[];
  /** Callback when a venue card is clicked — triggers navigation to VenueDetailStep */
  onSelectVenue: (id: string) => void;
  /** Search query value */
  searchQuery: string;
  /** Callback when search query changes */
  onSearchChange: (query: string) => void;
  /** Callback when search is submitted */
  onSearch?: (query: string) => void;
  /** Current filter state */
  filterValues: VenueFilterValues;
  /** Callback when any filter changes */
  onFilterChange: (values: VenueFilterValues) => void;
  /** Available venue type options */
  venueTypeOptions?: VenueTypeOption[];
  /** Available service tradition options for the autocomplete */
  traditionOptions?: string[];
  /** Current sort order */
  sortBy?: VenueSortBy;
  /** Callback when sort order changes */
  onSortChange?: (sort: VenueSortBy) => void;
  /** Current view mode */
  viewMode?: ListViewMode;
  /** Callback when view mode changes */
  onViewModeChange?: (mode: ListViewMode) => void;
  /** Callback for back navigation */
  onBack: () => void;
  /** Location name for the results count */
  locationName?: string;
  /** Whether this is a pre-planning flow */
  isPrePlanning?: boolean;
  /** Map panel content — slot for map integration */
  mapPanel?: React.ReactNode;
  /** Navigation bar — passed through to WizardLayout */
  navigation?: React.ReactNode;
  /** Progress stepper */
  progressStepper?: React.ReactNode;
  /** Running total widget (e.g. CartButton) */
  runningTotal?: React.ReactNode;
  /** MUI sx prop for the root */
  sx?: SxProps<Theme>;
}

// ─── Defaults ────────────────────────────────────────────────────────────────

const DEFAULT_VENUE_TYPES: VenueTypeOption[] = [
  { value: 'chapel', label: 'Chapel' },
  { value: 'church', label: 'Church' },
  { value: 'cathedral', label: 'Cathedral' },
  { value: 'outdoor', label: 'Outdoor Venue' },
  { value: 'hall', label: 'Hall / Room' },
  { value: 'mosque', label: 'Mosque' },
  { value: 'temple', label: 'Temple' },
];

const DEFAULT_TRADITIONS = [
  'None',
  'Anglican',
  "Bahá'í",
  'Baptist',
  'Buddhist',
  'Catholic',
  'Eastern Orthodox',
  'Hindu',
  'Humanist',
  'Indigenous Australian',
  'Jewish',
  'Lutheran',
  'Methodist',
  'Muslim',
  'Non-religious',
  'Pentecostal',
  'Presbyterian',
  'Salvation Army',
  'Secular',
  'Sikh',
  'Uniting Church',
];

const SORT_OPTIONS: { value: VenueSortBy; label: string }[] = [
  { value: 'recommended', label: 'Recommended' },
  { value: 'nearest', label: 'Nearest' },
  { value: 'price_low', label: 'Price: Low to High' },
  { value: 'price_high', label: 'Price: High to Low' },
];

export const EMPTY_VENUE_FILTERS: VenueFilterValues = {
  venueTypes: [],
  videoStreaming: false,
  photoDisplay: false,
  tradition: null,
};

// ─── Shared styles ───────────────────────────────────────────────────────────

const sectionHeadingSx = {
  mb: 1.5,
  display: 'block',
  fontWeight: 600,
  color: 'text.primary',
} as const;

const chipWrapSx = {
  display: 'flex',
  flexWrap: 'wrap',
  gap: 1,
} as const;

// ─── Component ───────────────────────────────────────────────────────────────

/**
 * Step 7 — Service Venue selection for the FA arrangement wizard.
 *
 * List + Map split layout. Left panel shows a scrollable list of
 * venue cards with search and filter button. Right panel is a
 * slot for map integration.
 *
 * Filters: location (chip-in-input), venue type (wrapping chips),
 * additional services (switches), service tradition (autocomplete).
 *
 * Click-to-navigate: clicking a venue card triggers navigation
 * to VenueDetailStep — no selection state or Continue button.
 *
 * Pure presentation component — props in, callbacks out.
 *
 * Spec: documentation/steps/steps/07_venue_consolidated.yaml
 */
export const VenueStep: React.FC<VenueStepProps> = ({
  venues,
  onSelectVenue,
  searchQuery,
  onSearchChange,
  onSearch,
  filterValues,
  onFilterChange,
  venueTypeOptions = DEFAULT_VENUE_TYPES,
  traditionOptions = DEFAULT_TRADITIONS,
  sortBy = 'recommended',
  onSortChange,
  viewMode = 'list',
  onViewModeChange,
  onBack,
  locationName,
  isPrePlanning = false,
  mapPanel,
  navigation,
  progressStepper,
  runningTotal,
  sx,
}) => {
  const [sortAnchor, setSortAnchor] = React.useState<null | HTMLElement>(null);

  const subheading = isPrePlanning
    ? 'Browse available venues. Your choice can be changed later.'
    : 'Choose a venue for the funeral service. You can filter by type, services, and tradition.';

  // ─── Active filter count ───
  const activeCount =
    (searchQuery.trim() ? 1 : 0) +
    filterValues.venueTypes.length +
    (filterValues.videoStreaming ? 1 : 0) +
    (filterValues.photoDisplay ? 1 : 0) +
    (filterValues.tradition ? 1 : 0);

  const handleClear = () => {
    onSearchChange('');
    onFilterChange(EMPTY_VENUE_FILTERS);
  };

  const handleVenueTypeToggle = (value: string) => {
    const current = filterValues.venueTypes;
    const next = current.includes(value) ? current.filter((v) => v !== value) : [...current, value];
    onFilterChange({ ...filterValues, venueTypes: next });
  };

  return (
    <WizardLayout
      variant="list-map"
      navigation={navigation}
      progressStepper={progressStepper}
      runningTotal={runningTotal}
      showBackLink
      backLabel="Back"
      onBack={onBack}
      sx={sx}
      secondaryPanel={
        <Box sx={{ position: 'relative', flex: 1, display: 'flex' }}>
          {/* Floating view toggle */}
          <ToggleButtonGroup
            value={viewMode}
            exclusive
            onChange={(_, val) => val && onViewModeChange?.(val as ListViewMode)}
            size="small"
            aria-label="View mode"
            sx={{
              position: 'absolute',
              top: 12,
              left: 12,
              zIndex: 1,
              bgcolor: 'background.paper',
              boxShadow: 'var(--fa-shadow-md)',
              borderRadius: 1,
              '& .MuiToggleButton-root': {
                px: 1.5,
                py: 0.5,
                fontSize: '0.75rem',
                fontWeight: 500,
                gap: 0.5,
                border: '1px solid',
                borderColor: 'divider',
                textTransform: 'none',
                '&.Mui-selected': {
                  bgcolor: 'var(--fa-color-brand-100)',
                  color: 'primary.main',
                  borderColor: 'primary.main',
                  '&:hover': { bgcolor: 'var(--fa-color-brand-200)' },
                },
              },
            }}
          >
            <ToggleButton value="list" aria-label="List view">
              <ViewListOutlinedIcon sx={{ fontSize: 16 }} />
              List
            </ToggleButton>
            <ToggleButton value="map" aria-label="Map view">
              <MapOutlinedIcon sx={{ fontSize: 16 }} />
              Map
            </ToggleButton>
          </ToggleButtonGroup>

          {/* Map content */}
          {mapPanel || (
            <Box
              sx={{
                flex: 1,
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                bgcolor: 'var(--fa-color-surface-cool)',
                borderLeft: '1px solid',
                borderColor: 'divider',
              }}
            >
              <Typography variant="body1" color="text.secondary">
                Map coming soon
              </Typography>
            </Box>
          )}
        </Box>
      }
    >
      {/* Heading — scrolls with listings */}
      <Typography variant="h4" component="h1" sx={{ mb: 0.5, pt: 2 }} tabIndex={-1}>
        Where would you like the service?
      </Typography>
      <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
        {subheading}
      </Typography>

      {/* Sticky controls — search + filters pinned while listings scroll */}
      <Box
        sx={{
          position: 'sticky',
          top: 0,
          zIndex: 1,
          bgcolor: 'background.default',
          pt: 3,
          pb: 1.5,
          mx: { xs: -2, md: -3 },
          px: { xs: 2, md: 3 },
          borderBottom: '1px solid',
          borderColor: 'divider',
        }}
      >
        {/* Location search */}
        <TextField
          placeholder="Search a town or suburb..."
          aria-label="Search venues by town or suburb"
          value={searchQuery}
          onChange={(e) => onSearchChange(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === 'Enter' && onSearch) {
              e.preventDefault();
              onSearch(searchQuery);
            }
          }}
          fullWidth
          size="small"
          InputProps={{
            startAdornment: (
              <InputAdornment position="start">
                <LocationOnOutlinedIcon sx={{ color: 'text.secondary', fontSize: 20 }} />
              </InputAdornment>
            ),
          }}
          sx={{ mb: 1.5 }}
        />

        {/* Control bar — filters + sort */}
        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
            gap: 1,
          }}
        >
          {/* Filters */}
          <FilterPanel activeCount={activeCount} onClear={handleClear}>
            {/* ── Location ── */}
            <Box>
              <Typography variant="labelLg" sx={sectionHeadingSx}>
                Location
              </Typography>
              <Autocomplete
                multiple
                freeSolo
                value={searchQuery.trim() ? [searchQuery.trim()] : []}
                onChange={(_, newValue) => {
                  const last = newValue[newValue.length - 1] ?? '';
                  onSearchChange(typeof last === 'string' ? last : '');
                }}
                options={[]}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    placeholder={searchQuery.trim() ? '' : 'Search a town or suburb...'}
                    size="small"
                    InputProps={{
                      ...params.InputProps,
                      startAdornment: (
                        <>
                          <InputAdornment position="start" sx={{ ml: 0.5 }}>
                            <LocationOnOutlinedIcon
                              sx={{ color: 'text.secondary', fontSize: 18 }}
                            />
                          </InputAdornment>
                          {params.InputProps.startAdornment}
                        </>
                      ),
                    }}
                  />
                )}
                size="small"
              />
            </Box>

            <Divider />

            {/* ── Venue type ── */}
            <Box>
              <Typography variant="labelLg" sx={sectionHeadingSx}>
                Venue type
              </Typography>
              <Box sx={chipWrapSx}>
                {venueTypeOptions.map((option) => (
                  <Chip
                    key={option.value}
                    label={option.label}
                    selected={filterValues.venueTypes.includes(option.value)}
                    onClick={() => handleVenueTypeToggle(option.value)}
                    variant="outlined"
                    size="small"
                  />
                ))}
              </Box>
            </Box>

            <Divider />

            {/* ── Additional services ── */}
            <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>
              <Typography variant="labelLg" sx={sectionHeadingSx}>
                Additional services
              </Typography>
              <FormControlLabel
                control={
                  <Switch
                    checked={filterValues.videoStreaming}
                    onChange={(_, checked) =>
                      onFilterChange({ ...filterValues, videoStreaming: checked })
                    }
                  />
                }
                label="Video streaming available"
                sx={{ mx: 0 }}
              />
              <FormControlLabel
                control={
                  <Switch
                    checked={filterValues.photoDisplay}
                    onChange={(_, checked) =>
                      onFilterChange({ ...filterValues, photoDisplay: checked })
                    }
                  />
                }
                label="Photo display available"
                sx={{ mx: 0 }}
              />
            </Box>

            <Divider />

            {/* ── Service tradition ── */}
            <Box>
              <Typography variant="labelLg" sx={sectionHeadingSx}>
                Service tradition
              </Typography>
              <Autocomplete
                value={filterValues.tradition}
                onChange={(_, newValue) => onFilterChange({ ...filterValues, tradition: newValue })}
                options={traditionOptions}
                renderInput={(params) => (
                  <TextField {...params} placeholder="Search traditions..." size="small" />
                )}
                clearOnEscape
                size="small"
              />
            </Box>
          </FilterPanel>

          {/* Sort — compact menu button, pushed right */}
          <Box sx={{ ml: 'auto' }}>
            <Button
              variant="outlined"
              color="secondary"
              size="small"
              startIcon={<SwapVertIcon sx={{ fontSize: 16 }} />}
              onClick={(e) => setSortAnchor(e.currentTarget)}
              aria-haspopup="listbox"
              sx={{ textTransform: 'none' }}
            >
              {SORT_OPTIONS.find((o) => o.value === sortBy)?.label ?? 'Sort'}
            </Button>
            <Menu
              anchorEl={sortAnchor}
              open={Boolean(sortAnchor)}
              onClose={() => setSortAnchor(null)}
              anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
              transformOrigin={{ vertical: 'top', horizontal: 'right' }}
            >
              {SORT_OPTIONS.map((opt) => (
                <MenuItem
                  key={opt.value}
                  selected={opt.value === sortBy}
                  onClick={() => {
                    onSortChange?.(opt.value);
                    setSortAnchor(null);
                  }}
                  sx={{ fontSize: '0.813rem' }}
                >
                  {opt.label}
                </MenuItem>
              ))}
            </Menu>
          </Box>
        </Box>

        {/* Results count — below controls */}
        <Typography
          variant="caption"
          color="text.secondary"
          sx={{ mt: 3, display: 'block' }}
          aria-live="polite"
        >
          {venues.length} venue{venues.length !== 1 ? 's' : ''}
          {locationName ? ` near ${locationName}` : ''} found
        </Typography>
      </Box>

      {/* Venue list — click-to-navigate */}
      <Box
        role="list"
        aria-label="Available venues"
        sx={{
          display: 'flex',
          flexDirection: 'column',
          gap: 2,
          pb: 3,
          pt: 2,
          px: { xs: 2, md: 3 },
          mx: { xs: -2, md: -3 },
          bgcolor: 'var(--fa-color-surface-subtle)',
        }}
      >
        {venues.map((venue) => (
          <VenueCard
            key={venue.id}
            name={venue.name}
            imageUrl={venue.imageUrl}
            location={venue.location}
            capacity={venue.capacity}
            price={venue.price}
            onClick={() => onSelectVenue(venue.id)}
            aria-label={`${venue.name}, ${venue.location}${venue.price ? `, $${venue.price}` : ''}`}
          />
        ))}

        {venues.length === 0 && (
          <Box sx={{ py: 6, textAlign: 'center' }}>
            <Typography variant="body1" color="text.secondary" sx={{ mb: 1 }}>
              No venues found in this area.
            </Typography>
            <Typography variant="body2" color="text.secondary">
              Try adjusting your search or clearing filters.
            </Typography>
          </Box>
        )}
      </Box>
    </WizardLayout>
  );
};

VenueStep.displayName = 'VenueStep';
export default VenueStep;
