/** Map layout, tile + crop definitions for Hearthroot Hollow. */

export const COLS = 22;
export const ROWS = 16;
export const TILE = 48;

export type TileKind = 'grass' | 'dirt' | 'soil' | 'water' | 'fence' | 'path' | 'sand' | 'house';

/** static decorations living on a tile (painted/sprited, never saved) */
export type Deco = 'rock' | 'mushroom' | 'log' | 'lantern' | 'scarecrow' | null;

export type CropType = 'turnip' | 'tomato' | 'sunflower' | 'pumpkin' | 'strawberry' | 'corn';

export interface CropDef {
  id: CropType;
  name: string;
  /** watered days needed for stage 0->1 and 1->2 */
  stageDays: [number, number];
  sell: number;
  color: string; // particle / UI accent
}

export const CROPS: CropDef[] = [
  { id: 'turnip', name: 'Turnip', stageDays: [1, 1], sell: 35, color: '#e89cc5' },
  { id: 'tomato', name: 'Tomato', stageDays: [1, 2], sell: 60, color: '#e8503a' },
  { id: 'sunflower', name: 'Sunflower', stageDays: [2, 2], sell: 90, color: '#f2c23e' },
  { id: 'pumpkin', name: 'Pumpkin', stageDays: [2, 3], sell: 140, color: '#e87f1e' },
  { id: 'strawberry', name: 'Strawberry', stageDays: [1, 2], sell: 70, color: '#e84a6f' },
  { id: 'corn', name: 'Corn', stageDays: [2, 2], sell: 100, color: '#f2d44e' },
];

export const cropDef = (id: CropType): CropDef => CROPS.find((c) => c.id === id)!;

export interface Crop {
  type: CropType;
  stage: 0 | 1 | 2;
  /** total watered days accumulated */
  progress: number;
}

export interface Tile {
  kind: TileKind;
  watered: boolean;
  crop: Crop | null;
  tree: boolean;
  deco: Deco;
}

/**
 * 22x16 map. F fence, W water (pond), S sand (beach corner), # path,
 * d dirt (pre-cleared field), H farmhouse footprint, . grass, T tree.
 * Decor: r rock, m mushroom, g fallen log, l lantern, c scarecrow.
 */
const LAYOUT = [
  'FFFFFFFFFFFFFFFFFFFFFF',
  'F....HHHH..T....WWWWWF',
  'F.T..HHHH......WWWWWWF',
  'F.dddddddd..l..SWWWWWF',
  'F.dddddddd....SSWWWW.F',
  'F.dddddddd.....SWWW..F',
  'F.dddddddd..T...SS..TF',
  'F.dddddddd.#.........F',
  'F.dddddddd.#....r....F',
  'Fc.........#...rr.r..F',
  'F..T...g...#....r....F',
  'F.m......T.#.....m...F',
  'F.T.....l..#...T...T.F',
  'F..........#..T......F',
  'F....m.....#....g..T.F',
  'FFFFFFFFFFF##FFFFFFFFF',
];

const DECO_CHARS: Record<string, Deco> = { r: 'rock', m: 'mushroom', g: 'log', l: 'lantern', c: 'scarecrow' };

export function makeWorld(): Tile[][] {
  if (import.meta.env.DEV) {
    if (LAYOUT.length !== ROWS || LAYOUT.some((r) => r.length !== COLS)) {
      throw new Error('LAYOUT does not match COLS x ROWS');
    }
  }
  const tiles: Tile[][] = [];
  for (let y = 0; y < ROWS; y++) {
    const row: Tile[] = [];
    for (let x = 0; x < COLS; x++) {
      const ch = LAYOUT[y][x];
      const kind: TileKind =
        ch === 'F' ? 'fence'
        : ch === 'W' ? 'water'
        : ch === 'S' ? 'sand'
        : ch === '#' ? 'path'
        : ch === 'd' ? 'dirt'
        : ch === 'H' ? 'house'
        : 'grass';
      row.push({ kind, watered: false, crop: null, tree: ch === 'T', deco: DECO_CHARS[ch] ?? null });
    }
    tiles.push(row);
  }
  return tiles;
}

/** the farmhouse footprint, derived from the layout (for sprite anchor + smoke) */
export function houseRect(): { x: number; y: number; w: number; h: number } {
  let minX = COLS, minY = ROWS, maxX = -1, maxY = -1;
  LAYOUT.forEach((row, y) => {
    for (let x = 0; x < COLS; x++) {
      if (row[x] === 'H') {
        minX = Math.min(minX, x); maxX = Math.max(maxX, x);
        minY = Math.min(minY, y); maxY = Math.max(maxY, y);
      }
    }
  });
  return { x: minX, y: minY, w: maxX - minX + 1, h: maxY - minY + 1 };
}

export function walkable(tiles: Tile[][], x: number, y: number): boolean {
  if (x < 0 || y < 0 || x >= COLS || y >= ROWS) return false;
  const t = tiles[y][x];
  if (t.kind === 'water' || t.kind === 'fence' || t.kind === 'house') return false;
  if (t.tree) return false;
  // mushrooms are small enough to step around; the rest blocks
  return t.deco === null || t.deco === 'mushroom';
}

/** can the hoe till this tile? */
export function tillable(t: Tile): boolean {
  return (t.kind === 'grass' || t.kind === 'dirt') && !t.tree && !t.crop && t.deco === null;
}

/** deterministic per-tile hash for stable procgen variation */
export function tileHash(x: number, y: number): number {
  let h = (x * 374761393 + y * 668265263) | 0;
  h = (h ^ (h >> 13)) * 1274126177;
  h = h ^ (h >> 16);
  return (h >>> 0) / 4294967296;
}
