package com.auto.clicker.autoclicker.room.repository;

import android.content.Context;

import com.auto.clicker.autoclicker.data.Event;
import com.auto.clicker.autoclicker.data.EventWrapper;
import com.auto.clicker.autoclicker.data.PointEvent;
import com.auto.clicker.autoclicker.data.SlideEvent;
import com.auto.clicker.autoclicker.room.AppDatabase;
import com.auto.clicker.autoclicker.room.SolutionWithEventsAndPoints;
import com.auto.clicker.autoclicker.room.dao.EventEntityDao;
import com.auto.clicker.autoclicker.room.dao.TouchPointDao;
import com.auto.clicker.autoclicker.room.dao.SolutionDao;
import com.auto.clicker.autoclicker.room.entity.EventEntity;
import com.auto.clicker.autoclicker.room.entity.TouchPoint;
import com.auto.clicker.autoclicker.room.entity.Solution;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.content.Context;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.util.Log; // Add Log import for debugging

public class EventRepository {
    private final SolutionDao solutionDao;
    private final TouchPointDao touchPointDao; // Renamed from PointDao
    private final EventEntityDao eventEntityDao;
    private final ExecutorService databaseWriteExecutor;

    public EventRepository(Context context) {
        AppDatabase db = AppDatabase.getInstance(context); // Updated to getInstance
        this.solutionDao = db.solutionDao();
        this.touchPointDao = db.pointDao(); // Assuming db.pointDao() returns TouchPointDao now
        this.eventEntityDao = db.eventEntityDao();
        this.databaseWriteExecutor = Executors.newFixedThreadPool(2);
    }

    // --- 插入操作 ---
    public void insertSolutionWithEvents(Solution solution, List<EventWrapper> runtimeEvents, RepositoryCallback<Long> callback) {
        databaseWriteExecutor.execute(() -> {
            long solutionId = -1; // Initialize solutionId outside try-catch for broader scope
            try {
                // 1. 插入 Solution
                solutionId = solutionDao.insertSolution(solution);
                if (solutionId == -1) {
                    throw new RuntimeException("Failed to insert solution.");
                }

                // 2. 遍历 runtimeEvents，插入 TouchPoint 和 EventEntity
                for (EventWrapper wrapper : runtimeEvents) {
                    Event event = wrapper.getEvent();
                    int order = wrapper.getOrder(); // Using order from EventWrapper

                    long eventEntityId = -1; // To store the result of event entity insertion

                    if (wrapper.getType() == EventWrapper.EventType.POINT && event instanceof PointEvent) {
                        PointEvent pointEvent = (PointEvent) event;
                        TouchPoint touchPoint = new TouchPoint(pointEvent.getX(), pointEvent.getY());
                        long pointId = touchPointDao.insertPoint(touchPoint);
                        if (pointId == -1)
                            throw new RuntimeException("Failed to insert touch point for PointEvent.");

                        // 调用 EventEntity 的唯一构造函数，将滑动相关字段设为 null 或默认值
                        EventEntity eventEntity = new EventEntity(
                                (int) solutionId, // Ensure type compatibility if solutionId is long
                                wrapper.getType().name(),
                                order,
                                pointId,    // clickPointId
                                null,       // slideStartPointId (null for point event)
                                null,       // slideEndPointId (null for point event)
                                0           // duration (0 for point event)
                        );
                        eventEntityId = eventEntityDao.insertEventEntity(eventEntity);
                        if (eventEntityId == -1)
                            throw new RuntimeException("Failed to insert EventEntity for PointEvent.");

                    } else if (wrapper.getType() == EventWrapper.EventType.SLIDE && event instanceof SlideEvent) {
                        SlideEvent slideEvent = (SlideEvent) event;
                        TouchPoint startTouchPoint = new TouchPoint(slideEvent.getStartPoint().getX(), slideEvent.getStartPoint().getY());
                        long startPointId = touchPointDao.insertPoint(startTouchPoint);
                        if (startPointId == -1)
                            throw new RuntimeException("Failed to insert start touch point for SlideEvent.");

                        TouchPoint endTouchPoint = new TouchPoint(slideEvent.getEndPoint().getX(), slideEvent.getEndPoint().getY());
                        long endPointId = touchPointDao.insertPoint(endTouchPoint);
                        if (endPointId == -1)
                            throw new RuntimeException("Failed to insert end touch point for SlideEvent.");

                        // 调用 EventEntity 的唯一构造函数，将点击相关字段设为 null
                        EventEntity eventEntity = new EventEntity(
                                (int) solutionId,
                                wrapper.getType().name(),
                                order,
                                null,
                                startPointId,
                                endPointId,
                                0
                        );
                        eventEntityId = eventEntityDao.insertEventEntity(eventEntity);
                        if (eventEntityId == -1)
                            throw new RuntimeException("Failed to insert EventEntity for SlideEvent.");
                    }
                }
                if (callback != null) {
                    // Post the result back to the main thread if needed for UI updates
                    // For simplicity, directly calling callback here; in a real app, use Handler or LiveData
                    callback.onComplete(solutionId);
                }
            } catch (Exception e) {
                Log.e("EventRepository", "Error inserting solution with events: " + e.getMessage(), e);
                // Consider rolling back the transaction if any part fails
                if (callback != null) {
                    callback.onError(e);
                }
            }
        });
    }

    // --- 查询操作 ---
    public void getAllSolutions(RepositoryCallback<List<Solution>> callback) {
        databaseWriteExecutor.execute(() -> {
            try {
                List<Solution> solutions = solutionDao.getAllSolutions();
                if (callback != null) callback.onComplete(solutions);
            } catch (Exception e) {
                Log.e("EventRepository", "Error getting all solutions: " + e.getMessage(), e);
                if (callback != null) callback.onError(e);
            }
        });
    }

    public void getSolutionWithEventsAndPoints(long solutionId, RepositoryCallback<SolutionWithEventsAndPoints> callback) {
        databaseWriteExecutor.execute(() -> {
            try {
                SolutionWithEventsAndPoints data = solutionDao.getSolutionWithEventsAndPoints(solutionId);
                if (callback != null) callback.onComplete(data);
            } catch (Exception e) {
                Log.e("EventRepository", "Error getting solution with events and points: " + e.getMessage(), e);
                if (callback != null) callback.onError(e);
            }
        });
    }

    // --- 删除操作 ---
    public void deleteSolution(Solution solution, RepositoryCallback<Integer> callback) {
        databaseWriteExecutor.execute(() -> {
            try {
                int rowsAffected = solutionDao.deleteSolution(solution);
                if (callback != null) callback.onComplete(rowsAffected);
            } catch (Exception e) {
                Log.e("EventRepository", "Error deleting solution: " + e.getMessage(), e);
                if (callback != null) callback.onError(e);
            }
        });
    }

    // 假设的回调接口，可以根据需要自定义
    public interface RepositoryCallback<T> {
        void onComplete(T result);

        void onError(Exception e);
    }
}