package com.dne.ems.config;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import com.dne.ems.dto.CityBlueprint;
import com.dne.ems.model.AqiRecord;
import com.dne.ems.model.Feedback;
import com.dne.ems.model.Grid;
import com.dne.ems.model.MapGrid;
import com.dne.ems.model.Task;
import com.dne.ems.model.UserAccount;
import com.dne.ems.model.enums.FeedbackStatus;
import com.dne.ems.model.enums.PollutionType;
import com.dne.ems.model.enums.Role;
import com.dne.ems.model.enums.SeverityLevel;
import com.dne.ems.model.enums.TaskStatus;
import com.dne.ems.model.enums.UserStatus;
import com.dne.ems.repository.AqiRecordRepository;
import com.dne.ems.repository.AssignmentRepository;
import com.dne.ems.repository.FeedbackRepository;
import com.dne.ems.repository.GridRepository;
import com.dne.ems.repository.MapGridRepository;
import com.dne.ems.repository.TaskRepository;
import com.dne.ems.repository.UserAccountRepository;

import lombok.RequiredArgsConstructor;

/**
 * Initializes the database with seed data upon application startup.
 * This component is crucial for setting up a baseline state for the application,
 * especially in development and testing environments. It populates grids, user accounts,
 * and other essential data.
 */
@Component
@RequiredArgsConstructor
public class DataInitializer implements CommandLineRunner {

    private final GridRepository gridRepository;
    private final UserAccountRepository userAccountRepository;
    private final PasswordEncoder passwordEncoder;
    private final AqiRecordRepository aqiRecordRepository;
    private final MapGridRepository mapGridRepository;
    private final TaskRepository taskRepository;
    private final AssignmentRepository assignmentRepository;
    private final FeedbackRepository feedbackRepository;

    private static final Logger log = LoggerFactory.getLogger(DataInitializer.class);

    @Override
    public void run(String... args) {
        log.info("Starting data initialization...");
        try {
            initializeGridData();
            initializeMapGridData(); // Ensure MapGrid is synchronized
            initializeUsers();
            initializeAqiData();
            initializeFeedbackData();
            initializeTaskData();
        } catch (Exception e) {
            log.error("Error during data initialization", e);
        }
        log.info("Data initialization finished.");
    }

    private void initializeGridData() {
        if (gridRepository.count() > 0) {
            log.info("Grid data already exists. Skipping initialization.");
            return;
        }
        log.info("Creating initial grid data...");

        final int MAP_SIZE = 40;
        final double OBSTACLE_CHANCE = 0.05; // 5% chance for a cell to be an obstacle

        Grid[][] map = new Grid[MAP_SIZE][MAP_SIZE];
        Random random = new Random();
        List<Grid> gridsToSave = new ArrayList<>();
        
        // 1. Define the 4 cities
        List<CityBlueprint> cityBlueprints = List.of(
            new CityBlueprint("常州市", "溧阳市", 0, 0, 0, 0),
            new CityBlueprint("无锡市", "宜兴市", 0, 0, 0, 0),
            new CityBlueprint("苏州市", "昆山市", 0, 0, 0, 0),
            new CityBlueprint("南京市", "江宁区", 0, 0, 0, 0)
        );

        // 2. Select 4 unique random seeds (capitals) for the cities
        Queue<Point> expansionQueue = new LinkedList<>();
        Set<Point> usedSeeds = new HashSet<>();

        for (CityBlueprint city : cityBlueprints) {
            Point seed;
            do {
                seed = new Point(random.nextInt(MAP_SIZE), random.nextInt(MAP_SIZE));
            } while (usedSeeds.contains(seed));
            
            usedSeeds.add(seed);
            
            Grid grid = new Grid();
            grid.setGridX(seed.x);
            grid.setGridY(seed.y);
            grid.setCityName(city.getCityName());
            grid.setDistrictName(city.getDistrictName());
            grid.setIsObstacle(false); // Capitals are never obstacles
            
            map[seed.x][seed.y] = grid;
            expansionQueue.add(seed);
        }

        // 3. Expand all cities simultaneously using Breadth-First Search (BFS)
        // This ensures every cell belongs to the closest city, creating Voronoi-like regions
        while (!expansionQueue.isEmpty()) {
            Point p = expansionQueue.poll();
            Grid centerGrid = map[p.x][p.y];

            // Use shuffled neighbors to make borders more irregular and interesting
            for (Point neighbor : p.getShuffledNeighbors(MAP_SIZE, MAP_SIZE, random)) {
                if (map[neighbor.x][neighbor.y] == null) { // If the cell is unclaimed
                    Grid neighborGrid = new Grid();
                    neighborGrid.setGridX(neighbor.x);
                    neighborGrid.setGridY(neighbor.y);
                    neighborGrid.setCityName(centerGrid.getCityName());
                    neighborGrid.setDistrictName(centerGrid.getDistrictName());
                    neighborGrid.setIsObstacle(false); // Set obstacle status later
                    
                    map[neighbor.x][neighbor.y] = neighborGrid;
                    expansionQueue.add(neighbor);
                }
            }
        }
        
        // 4. Identify border cells to keep them clear of obstacles
        Set<Point> borderCells = new HashSet<>();
        for (int x = 0; x < MAP_SIZE; x++) {
            for (int y = 0; y < MAP_SIZE; y++) {
                Grid currentGrid = map[x][y];
                if (currentGrid == null) {
                    // This should never happen as we ensure every cell is assigned to a city
                    log.error("发现未分配城市的格子 at ({}, {}), 这是一个错误", x, y);
                    continue;
                }

                Point currentPoint = new Point(x, y);
                for (Point neighbor : currentPoint.getNeighbors(MAP_SIZE, MAP_SIZE)) {
                    Grid neighborGrid = map[neighbor.x][neighbor.y];
                    if (neighborGrid != null && !currentGrid.getCityName().equals(neighborGrid.getCityName())) {
                        borderCells.add(currentPoint);
                        break; // Found one neighbor from another city, this is a border cell
                    }
                }
            }
        }

        // 5. Add random obstacles, avoiding borders and capitals
        for (int x = 0; x < MAP_SIZE; x++) {
            for (int y = 0; y < MAP_SIZE; y++) {
                Grid grid = map[x][y];
                if (grid != null) {
                    boolean isSeed = usedSeeds.contains(new Point(x, y));
                    boolean isBorder = borderCells.contains(new Point(x, y));

                    // Don't make capitals or border cells obstacles
                    if (!isSeed && !isBorder && random.nextDouble() < OBSTACLE_CHANCE) {
                        grid.setIsObstacle(true);
                    }
                    gridsToSave.add(grid);
                } else {
                    // This should never happen - log an error if it does
                    log.error("发现空格子 at ({}, {}), 这是一个算法错误", x, y);
                }
            }
        }
        
        gridRepository.saveAll(gridsToSave);
        log.info("{} grid cells created.", gridsToSave.size());
    }
    
    /**
     * Synchronizes the grid data with the map_grid table for A* pathfinding.
     */
    private void initializeMapGridData() {
        if (mapGridRepository.count() > 0) {
            log.info("MapGrid data already exists. Skipping synchronization.");
            return;
        }
        log.info("Synchronizing data to MapGrid for pathfinding...");

        List<Grid> grids = gridRepository.findAll();
        List<MapGrid> mapGrids = grids.stream()
            .map(grid -> MapGrid.builder()
                .x(grid.getGridX())
                .y(grid.getGridY())
                .isObstacle(grid.getIsObstacle())
                .cityName(grid.getCityName())
                .build())
            .collect(Collectors.toList());

        mapGridRepository.saveAll(mapGrids);
        log.info("Synchronized {} grid cells to MapGrid.", mapGrids.size());
    }

    private void initializeUsers() {
        if (userAccountRepository.count() > 0) {
            log.info("User data already exists. Skipping initialization.");
            return;
        }
        log.info("Creating initial user accounts...");
    
        // Create Admin
        UserAccount admin = new UserAccount();
        admin.setName("系统管理员");
        admin.setEmail("admin@example.com");
        admin.setPhone("13800138000");
        admin.setPassword(passwordEncoder.encode("password"));
        admin.setRole(Role.ADMIN);
        admin.setStatus(UserStatus.ACTIVE);
    
        // Create Decision Maker
        UserAccount decisionMaker = new UserAccount();
        decisionMaker.setName("决策者");
        decisionMaker.setEmail("decision@example.com");
        decisionMaker.setPhone("13900139000");
        decisionMaker.setPassword(passwordEncoder.encode("password"));
        decisionMaker.setRole(Role.DECISION_MAKER);
        decisionMaker.setStatus(UserStatus.ACTIVE);
    
        // Create Supervisors
        UserAccount supervisor1 = new UserAccount();
        supervisor1.setName("主管A");
        supervisor1.setEmail("supervisor1@example.com");
        supervisor1.setPhone("13700137001");
        supervisor1.setPassword(passwordEncoder.encode("password"));
        supervisor1.setRole(Role.SUPERVISOR);
        supervisor1.setStatus(UserStatus.ACTIVE);
        supervisor1.setRegion("南京市");
        
        UserAccount supervisor2 = new UserAccount();
        supervisor2.setName("主管B");
        supervisor2.setEmail("supervisor2@example.com");
        supervisor2.setPhone("13700137002");
        supervisor2.setPassword(passwordEncoder.encode("password"));
        supervisor2.setRole(Role.SUPERVISOR);
        supervisor2.setStatus(UserStatus.ACTIVE);
        supervisor2.setRegion("无锡市");
        
        // 添加特定的主管用户，用于任务初始化
        UserAccount specialSupervisor = new UserAccount();
        specialSupervisor.setName("特定主管");
        specialSupervisor.setEmail("supervisor@aizhangz.top");
        specialSupervisor.setPhone("13700137003");
        specialSupervisor.setPassword(passwordEncoder.encode("password"));
        specialSupervisor.setRole(Role.SUPERVISOR);
        specialSupervisor.setStatus(UserStatus.ACTIVE);
        specialSupervisor.setRegion("苏州市");
        
        // 添加公众监督员，用于反馈初始化
        UserAccount publicSupervisor = new UserAccount();
        publicSupervisor.setName("公众监督员");
        publicSupervisor.setEmail("public.supervisor@aizhangz.top");
        publicSupervisor.setPhone("13700137004");
        publicSupervisor.setPassword(passwordEncoder.encode("password"));
        publicSupervisor.setRole(Role.PUBLIC_SUPERVISOR);
        publicSupervisor.setStatus(UserStatus.ACTIVE);
    
        userAccountRepository.saveAll(List.of(admin, decisionMaker, supervisor1, supervisor2, specialSupervisor, publicSupervisor));
    
        // Create Grid Workers
        List<UserAccount> workers = new ArrayList<>();
        List<Grid> availableGrids = gridRepository.findByIsObstacle(false);
    
        int workerCount = 0;
        for (Grid grid : availableGrids) {
            if (workerCount >= 50) break; // Create up to 50 workers
    
            UserAccount worker = new UserAccount();
            worker.setName("网格员" + (workerCount + 1));
            worker.setPhone("1470000" + String.format("%04d", workerCount));
            worker.setEmail("worker" + (workerCount + 1) + "@example.com");
            worker.setPassword(passwordEncoder.encode("password"));
            worker.setRole(Role.GRID_WORKER);
            worker.setStatus(UserStatus.ACTIVE);
            worker.setGridX(grid.getGridX());
            worker.setGridY(grid.getGridY());
            worker.setRegion(grid.getCityName());
            worker.setGender(workerCount % 2 == 0 ? com.dne.ems.model.enums.Gender.MALE : com.dne.ems.model.enums.Gender.FEMALE);
            workers.add(worker);
            workerCount++;
        }
        
        // 添加特定的网格员，用于任务初始化
        UserAccount specialWorker = new UserAccount();
        specialWorker.setName("特定网格员");
        specialWorker.setPhone("14700009999");
        specialWorker.setEmail("worker@aizhangz.top");
        specialWorker.setPassword(passwordEncoder.encode("password"));
        specialWorker.setRole(Role.GRID_WORKER);
        specialWorker.setStatus(UserStatus.ACTIVE);
        specialWorker.setGridX(10);
        specialWorker.setGridY(10);
        specialWorker.setRegion("苏州市");
        specialWorker.setGender(com.dne.ems.model.enums.Gender.MALE);
        workers.add(specialWorker);
        
        userAccountRepository.saveAll(workers);
    
        log.info("Created Admin, DecisionMaker, 2 Supervisors, and {} Grid Workers.", workers.size());
    }

    private void initializeAqiData() {
        if (aqiRecordRepository.count() > 0) {
            log.info("AQI data already exists. Skipping initialization.");
            return;
        }
        log.info("Creating initial AQI data...");
        
        // 清空现有数据
        aqiRecordRepository.deleteAll();
        
        List<AqiRecord> records = new ArrayList<>();
        
        // 获取网格数据，用于关联
        List<Grid> grids = gridRepository.findAll();
        if (grids.isEmpty()) {
            log.warn("没有找到网格数据，无法完全初始化AQI数据");
            // 即使没有网格数据，也继续初始化基本的 AQI 数据
        }
        
        // 为不同城市选择不同的网格
        // Map<String, List<Grid>> gridsByCity = grids.stream()
        //         .collect(Collectors.groupingBy(Grid::getCityName));
        
        // 基本 AQI 数据 - 不同级别
        // Good (0-50)
        AqiRecord record1 = new AqiRecord("北京市", 40, LocalDateTime.now().minusDays(1), 10.5, 20.3, 5.1, 15.2, 0.8, 30.1);
        record1.setGridX(0);
        record1.setGridY(0);
        records.add(record1);
        
        AqiRecord record2 = new AqiRecord("上海市", 35, LocalDateTime.now().minusDays(2), 9.2, 18.5, 4.8, 14.0, 0.7, 28.5);
        record2.setGridX(0);
        record2.setGridY(1);
        records.add(record2);
        
        // Moderate (51-100)
        AqiRecord record3 = new AqiRecord("广州市", 75, LocalDateTime.now().minusDays(3), 25.3, 45.7, 10.2, 30.5, 1.5, 60.2);
        record3.setGridX(1);
        record3.setGridY(0);
        records.add(record3);
        
        AqiRecord record4 = new AqiRecord("深圳市", 85, LocalDateTime.now().minusDays(4), 28.6, 52.1, 12.3, 35.8, 1.8, 68.5);
        record4.setGridX(1);
        record4.setGridY(1);
        records.add(record4);
        
        // Unhealthy for Sensitive Groups (101-150)
        AqiRecord record5 = new AqiRecord("成都市", 130, LocalDateTime.now().minusDays(5), 45.2, 85.3, 20.5, 55.8, 3.2, 90.5);
        record5.setGridX(2);
        record5.setGridY(0);
        records.add(record5);
        
        // Unhealthy (151-200)
        AqiRecord record6 = new AqiRecord("武汉市", 175, LocalDateTime.now().minusDays(6), 60.5, 110.8, 30.2, 70.5, 4.5, 120.3);
        record6.setGridX(2);
        record6.setGridY(1);
        records.add(record6);
        
        // Very Unhealthy (201-300)
        AqiRecord record7 = new AqiRecord("西安市", 250, LocalDateTime.now().minusDays(7), 90.3, 160.5, 45.8, 95.2, 6.8, 150.5);
        record7.setGridX(3);
        record7.setGridY(0);
        records.add(record7);
        
        // Hazardous (301+)
        AqiRecord record8 = new AqiRecord("兰州市", 320, LocalDateTime.now().minusDays(8), 120.5, 200.8, 60.2, 120.5, 8.5, 180.3);
        record8.setGridX(3);
        record8.setGridY(1);
        records.add(record8);
        
        // 保存基本数据
        List<AqiRecord> savedRecords = aqiRecordRepository.saveAll(records);
        log.info("已保存基本 AQI 数据: {} 条记录", savedRecords.size());
        records.clear();
        
        // 添加带有网格位置的数据 - 用于热力图
        // 直接使用网格坐标，不关联 Grid 实体
        for (int x = 0; x < 5; x++) {
            for (int y = 0; y < 5; y++) {
                int aqiValue = 50 + (x + y) * 15; // 不同 AQI 值
                LocalDateTime recordTime = LocalDateTime.now().minusDays(x + y);
                
                AqiRecord record = new AqiRecord("北京市", aqiValue, recordTime, 
                    20.0 + x, 40.0 + y * 2, 8.0 + x, 25.0 + y, 1.0 + x * 0.2, 50.0 + y * 3);
                record.setGridX(x);
                record.setGridY(y);
                records.add(record);
            }
        }
        
        // 保存热力图数据
        savedRecords = aqiRecordRepository.saveAll(records);
        log.info("已保存热力图 AQI 数据: {} 条记录", savedRecords.size());
        records.clear();
        
        // 添加不同月份的数据 - 用于趋势图
        for (int i = 1; i <= 6; i++) {
            for (int j = 0; j < 3; j++) {  // 每个月添加多条记录
                LocalDateTime recordTime = LocalDateTime.now().minusMonths(i).plusDays(j * 5);
                int aqiValue = 80 + i * 20 + j * 5; // 确保有些超过 100 的值
                
                AqiRecord record = new AqiRecord("北京市", aqiValue, recordTime, 
                    30.0 + i, 60.0 + i * 2, 12.0 + i, 35.0 + i, 1.5 + i * 0.2, 70.0 + i * 3);
                // 为趋势数据也设置网格坐标
                record.setGridX(i % 5);
                record.setGridY(j % 5);
                records.add(record);
            }
        }
        
        // 保存趋势图数据
        savedRecords = aqiRecordRepository.saveAll(records);
        log.info("已保存趋势图 AQI 数据: {} 条记录", savedRecords.size());
        
        log.info("Created {} AQI records.", records.size());
        aqiRecordRepository.saveAll(records);
    }

    private void initializeFeedbackData() {
        if (feedbackRepository.count() > 0) {
            log.info("Feedback 数据已存在，跳过初始化");
            return;
        }

        // 清除现有数据并重新初始化
        // 必须先清除子表数据，再清除父表数据，以避免外键约束冲突
        assignmentRepository.deleteAll();
        taskRepository.deleteAll();
        feedbackRepository.deleteAll();
        log.info("已清除现有的 Assignment, Task, 和 Feedback 数据，开始重新初始化...");

        // 使用PUBLIC_SUPERVISOR角色的用户作为反馈提交者
        UserAccount reporter = userAccountRepository.findByEmail("public.supervisor@aizhangz.top").orElse(null);
        if (reporter == null) {
            log.warn("无法找到公众监督员 'public.supervisor@aizhangz.top'，跳过 Feedback 初始化");
            return;
        }
        
        // 创建反馈数据
        List<Feedback> feedbacks = new ArrayList<>();

        Feedback feedback1 = new Feedback();
        feedback1.setEventId("FB-202301");
        feedback1.setTitle("工业区PM2.5超标");
        feedback1.setDescription("市中心化工厂在夜间排放黄色烟雾，气味刺鼻。");
        feedback1.setLatitude(39.9042);
        feedback1.setLongitude(116.4074);
        feedback1.setGridX(5);
        feedback1.setGridY(5);
        feedback1.setPollutionType(PollutionType.PM25);
        feedback1.setSeverityLevel(SeverityLevel.HIGH);
        feedback1.setStatus(FeedbackStatus.PENDING_ASSIGNMENT);
        feedback1.setUser(reporter);
        feedback1.setSubmitterId(reporter.getId());
        feedbacks.add(feedback1);

        Feedback feedback2 = new Feedback();
        feedback2.setEventId("FB-202302");
        feedback2.setTitle("交通要道NO2浓度过高");
        feedback2.setDescription("主干道车辆拥堵，空气质量差。");
        feedback2.setLatitude(39.915);
        feedback2.setLongitude(116.400);
        feedback2.setGridX(6);
        feedback2.setGridY(6);
        feedback2.setPollutionType(PollutionType.NO2);
        feedback2.setSeverityLevel(SeverityLevel.MEDIUM);
        feedback2.setStatus(FeedbackStatus.ASSIGNED);
        feedback2.setUser(reporter);
        feedback2.setSubmitterId(reporter.getId());
        feedbacks.add(feedback2);

        Feedback feedback3 = new Feedback();
        feedback3.setEventId("FB-202303");
        feedback3.setTitle("未知来源的SO2异味");
        feedback3.setDescription("居民区闻到类似烧煤的刺鼻气味。");
        feedback3.setLatitude(39.888);
        feedback3.setLongitude(116.356);
        feedback3.setGridX(7);
        feedback3.setGridY(7);
        feedback3.setPollutionType(PollutionType.SO2);
        feedback3.setSeverityLevel(SeverityLevel.LOW);
        feedback3.setStatus(FeedbackStatus.PROCESSED);
        feedback3.setUser(reporter);
        feedback3.setSubmitterId(reporter.getId());
        feedbacks.add(feedback3);

        feedbackRepository.saveAll(feedbacks);
        log.info("反馈数据初始化完成，共创建 {} 条记录", feedbacks.size());
    }

    private void initializeTaskData() {
        if (taskRepository.count() > 0) {
            log.info("Task 数据已存在，跳过初始化");
            return;
        }
        log.info("开始初始化 Task 模拟数据...");

        UserAccount worker = userAccountRepository.findByEmail("worker@aizhangz.top").orElse(null);
        if (worker == null) {
            log.warn("无法找到网格员 'worker@aizhangz.top'，跳过 Task 初始化");
            return;
        }
        
        UserAccount creator = userAccountRepository.findByEmail("supervisor@aizhangz.top").orElse(null);
        if (creator == null) {
            log.warn("无法找到主管 'supervisor@aizhangz.top'，跳过 Task 初始化");
            return;
        }

        List<Task> tasks = new ArrayList<>();

        Task task1 = new Task();
        task1.setTitle("调查PM2.5超标问题");
        task1.setDescription("前往工业区，使用便携式检测仪检测空气质量，并记录排放情况。");
        task1.setAssignee(worker);
        task1.setCreatedBy(creator);
        task1.setStatus(TaskStatus.IN_PROGRESS);
        task1.setAssignedAt(LocalDateTime.now().minusDays(2));
        task1.setLatitude(39.9042);
        task1.setLongitude(116.4074);
        task1.setGridX(2);
        task1.setGridY(3);
        task1.setSeverityLevel(SeverityLevel.HIGH);
        tasks.add(task1);

        Task task2 = new Task();
        task2.setTitle("疏导交通并监测NO2");
        task2.setDescription("在交通要道关键节点进行监测，并与交管部门协调。");
        task2.setAssignee(worker);
        task2.setCreatedBy(creator);
        task2.setStatus(TaskStatus.COMPLETED);
        task2.setCompletedAt(LocalDateTime.now().minusDays(1));
        task2.setAssignedAt(LocalDateTime.now().minusDays(4));
        task2.setLatitude(39.915);
        task2.setLongitude(116.400);
        task2.setGridX(4);
        task2.setGridY(5);
        task2.setSeverityLevel(SeverityLevel.MEDIUM);
        tasks.add(task2);

        Task task3 = new Task();
        task3.setTitle("排查SO2异味源");
        task3.setDescription("在相关居民区进行走访和气味溯源。");
        task3.setAssignee(worker);
        task3.setCreatedBy(creator);
        task3.setStatus(TaskStatus.ASSIGNED);
        task3.setAssignedAt(LocalDateTime.now());
        task3.setLatitude(39.888);
        task3.setLongitude(116.356);
        task3.setGridX(6);
        task3.setGridY(7);
        task3.setSeverityLevel(SeverityLevel.LOW);
        tasks.add(task3);

        taskRepository.saveAll(tasks);
        log.info("Task 数据初始化完成，共创建 {} 条记录", tasks.size());
    }

    // Helper class for coordinates
    private static class Point {
        int x, y;
        // Point class implementation...
        Point(int x, int y) { this.x = x; this.y = y; }
        @Override public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Point point = (Point) o;
            return x == point.x && y == point.y;
        }
        @Override public int hashCode() {
            return java.util.Objects.hash(x, y);
        }

        List<Point> getShuffledNeighbors(int width, int height, Random rand) {
            List<Point> neighbors = getNeighbors(width, height);
            Collections.shuffle(neighbors, rand);
            return neighbors;
        }

        List<Point> getNeighbors(int width, int height) {
            List<Point> neighbors = new ArrayList<>();
            if (x > 0) neighbors.add(new Point(x - 1, y));
            if (x < width - 1) neighbors.add(new Point(x + 1, y));
            if (y > 0) neighbors.add(new Point(x, y - 1));
            if (y < height - 1) neighbors.add(new Point(x, y + 1));
            return neighbors;
        }
    }
}