import { create } from 'zustand';
import { getDBConnection } from '@/database/sqlite';
import { Trackpoint, MediaAttachment } from '@/types/workout.types';
import { calculateDistance, calculateMetKcal } from '@/utils/calculations';

interface WorkoutState {
  isTracking: boolean;
  workoutType: 'RUNNING' | 'CYCLING' | 'WALKING';
  currentWorkoutId: string | null;
  routePoints: Trackpoint[];
  mediaAttachments: MediaAttachment[];
  distance: number; // km
  duration: number; // seconds
  currentSpeed: number; // km/h
  currentHeartRate: number; // bpm
  caloriesBurned: number; // kcal
  weightKg: number; // mặc định dùng 70kg để tính MET

  startWorkout: (type: 'RUNNING' | 'CYCLING' | 'WALKING') => void;
  stopWorkout: () => Promise<string | null>;
  addTrackpoint: (point: Trackpoint) => void;
  addMediaAttachment: (media: MediaAttachment) => void;
  updateTimer: () => void;
}

export const useWorkoutStore = create<WorkoutState>((set, get) => ({
  isTracking: false,
  workoutType: 'RUNNING',
  currentWorkoutId: null,
  routePoints: [],
  mediaAttachments: [],
  distance: 0,
  duration: 0,
  currentSpeed: 0,
  currentHeartRate: 75,
  caloriesBurned: 0,
  weightKg: 70,

  startWorkout: (type) => {
    const id = `WK_${Date.now()}`;
    set({
      isTracking: true,
      workoutType: type,
      currentWorkoutId: id,
      routePoints: [],
      mediaAttachments: [],
      distance: 0,
      duration: 0,
      currentSpeed: 0,
      currentHeartRate: 75,
      caloriesBurned: 0,
    });
  },

  addTrackpoint: (point) => {
    const { routePoints, distance, weightKg, workoutType } = get();
    let newDistance = distance;

    if (routePoints.length > 0) {
      const lastPt = routePoints[routePoints.length - 1];
      const d = calculateDistance(lastPt.lat, lastPt.lng, point.lat, point.lng);
      newDistance += d;
    }

    const newlyBurnedKcal = calculateMetKcal(workoutType, weightKg, point.hr, 10);

    set((state) => ({
      routePoints: [...state.routePoints, point],
      distance: newDistance,
      currentSpeed: point.speed,
      currentHeartRate: point.hr,
      caloriesBurned: state.caloriesBurned + newlyBurnedKcal,
    }));
  },

  addMediaAttachment: (media) => {
    set((state) => ({
      mediaAttachments: [...state.mediaAttachments, media],
    }));
  },

  updateTimer: () => {
    set((state) => ({ duration: state.duration + 1 }));
  },

  stopWorkout: async () => {
    const { currentWorkoutId, workoutType, distance, duration, routePoints, mediaAttachments, caloriesBurned } = get();
    if (!currentWorkoutId) return null;

    set({ isTracking: false });

    try {
      const db = await getDBConnection();
      const avgSpeed = duration > 0 ? (distance / (duration / 3600)) : 0;
      const totalHR = routePoints.reduce((acc, p) => acc + p.hr, 0);
      const avgHR = routePoints.length > 0 ? Math.round(totalHR / routePoints.length) : 75;
      const todayStr = new Date().toISOString().split('T')[0];

      // 1. Lưu vào bảng Workouts
      await db.runAsync(
        `INSERT INTO workouts (id, title, type, date, start_time, duration, distance, avg_speed, avg_hr, calories) 
         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
        [currentWorkoutId, `Hành trình ${workoutType}`, workoutType, todayStr, Date.now(), duration, distance, avgSpeed, avgHR, Math.round(caloriesBurned)]
      );

      // 2. Lưu các Trackpoints
      for (const p of routePoints) {
        await db.runAsync(
          `INSERT INTO trackpoints (workout_id, latitude, longitude, speed, heart_rate, timestamp) VALUES (?, ?, ?, ?, ?, ?)`,
          [currentWorkoutId, p.lat, p.lng, p.speed, p.hr, p.timestamp]
        );
      }

      // 3. Lưu các Media đính kèm
      for (const m of mediaAttachments) {
        await db.runAsync(
          `INSERT INTO media_attachments (workout_id, latitude, longitude, type, file_uri, caption, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)`,
          [currentWorkoutId, m.lat, m.lng, m.type, m.uri, m.caption ?? null, Date.now()]
        );
      }

      return currentWorkoutId;
    } catch (error) {
      console.error("Lỗi khi lưu trữ SQLite:", error);
      return null;
    }
  }
}));
