import type { FeatureMeta, FeatureFilters, ViewState } from '../types';

export const DEFAULT_VIEW: ViewState = {
  longitude: -1.5,
  latitude: 53.5,
  zoom: 6,
  pitch: 0,
};

export function parseUrlState(): {
  viewState?: ViewState;
  filters?: FeatureFilters;
  poiCategories?: Set<string>;
  tab?: 'pois' | 'properties' | 'area';
} {
  const params = new URLSearchParams(window.location.search);
  const result: ReturnType<typeof parseUrlState> = {};

  const v = params.get('v');
  if (v) {
    const parts = v.split(',').map(Number);
    if (parts.length === 3 && parts.every((n) => !isNaN(n))) {
      result.viewState = {
        latitude: parts[0],
        longitude: parts[1],
        zoom: parts[2],
        pitch: 0,
      };
    }
  }

  const f = params.get('f');
  if (f) {
    const filters: FeatureFilters = {};
    for (const segment of f.split(',')) {
      const colonIdx = segment.indexOf(':');
      if (colonIdx === -1) continue;
      const name = segment.substring(0, colonIdx);
      const rest = segment.substring(colonIdx + 1);
      if (rest.includes(':')) {
        const [minStr, maxStr] = rest.split(':');
        const min = Number(minStr);
        const max = Number(maxStr);
        if (!isNaN(min) && !isNaN(max)) {
          filters[name] = [min, max];
        }
      } else if (rest.includes('|')) {
        filters[name] = rest.split('|');
      } else {
        filters[name] = [rest];
      }
    }
    if (Object.keys(filters).length > 0) {
      result.filters = filters;
    }
  }

  const poi = params.get('poi');
  if (poi) {
    result.poiCategories = new Set(poi.split(',').filter(Boolean));
  }

  const tab = params.get('tab');
  if (tab === 'p') result.tab = 'properties';
  else if (tab === 'o') result.tab = 'pois';
  else if (tab === 'a') result.tab = 'area';

  return result;
}

export function stateToParams(
  viewState: { latitude: number; longitude: number; zoom: number } | null,
  filters: FeatureFilters,
  features: FeatureMeta[],
  selectedPOICategories: Set<string>,
  rightPaneTab: 'pois' | 'properties' | 'area'
): URLSearchParams {
  const params = new URLSearchParams();

  if (viewState) {
    params.set(
      'v',
      `${viewState.latitude.toFixed(4)},${viewState.longitude.toFixed(4)},${viewState.zoom.toFixed(1)}`
    );
  }

  const filterEntries = Object.entries(filters);
  if (filterEntries.length > 0) {
    const filtersStr = filterEntries
      .map(([name, value]) => {
        const meta = features.find((f) => f.name === name);
        if (meta?.type === 'enum') {
          return `${name}:${(value as string[]).join('|')}`;
        }
        const [min, max] = value as [number, number];
        return `${name}:${min}:${max}`;
      })
      .join(',');
    params.set('f', filtersStr);
  }

  if (selectedPOICategories.size > 0) {
    params.set('poi', Array.from(selectedPOICategories).join(','));
  }

  if (rightPaneTab === 'properties') {
    params.set('tab', 'p');
  } else if (rightPaneTab === 'area') {
    params.set('tab', 'a');
  }

  return params;
}
