<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="vehicleTrip">

  <!-- ═══════════════════════════════════════════════════
       동적 검색 조건 (getVehicleTripList / Cnt 공통)
       ═══════════════════════════════════════════════════ -->
  <sql id="vehicleTripSearchCondition">
    AND (vts.company_code = #{company_code} OR vts.company_code = '*')
    <if test="user_id != null and user_id != ''">
      AND vts.user_id = #{user_id}
    </if>
    <if test="vehicle_id != null">
      AND vts.vehicle_id = #{vehicle_id}
    </if>
    <if test="status != null and status != ''">
      AND vts.status = #{status}
    </if>
    <if test="start_date != null and start_date != ''">
      AND DATE(vts.start_time) &gt;= #{start_date}::date
    </if>
    <if test="end_date != null and end_date != ''">
      AND DATE(vts.start_time) &lt;= #{end_date}::date
    </if>
    <if test="departure != null and departure != ''">
      AND vts.departure = #{departure}
    </if>
    <if test="arrival != null and arrival != ''">
      AND vts.arrival = #{arrival}
    </if>
  </sql>

  <!-- 운행 이력 목록 (user_info, vehicles JOIN) -->
  <select id="getVehicleTripList" parameterType="map" resultType="map">
    SELECT
      vts.trip_id, vts.user_id, vts.vehicle_id,
      vts.departure, vts.arrival, vts.departure_name, vts.destination_name,
      vts.start_time, vts.end_time, vts.status,
      vts.total_distance, vts.duration_minutes, vts.location_count,
      vts.company_code,
      ui.user_name, v.vehicle_number

    FROM vehicle_trip_summary vts
    LEFT JOIN user_info ui ON vts.user_id = ui.user_id
    LEFT JOIN vehicles v ON vts.vehicle_id = v.id

    WHERE 1=1
    <include refid="vehicleTripSearchCondition"/>

    ORDER BY vts.start_time DESC
    <include refid="common.pagination"/>
  </select>

  <select id="getVehicleTripListCnt" parameterType="map" resultType="int">
    SELECT COUNT(*)

    FROM vehicle_trip_summary vts

    WHERE 1=1
    <include refid="vehicleTripSearchCondition"/>
  </select>

  <!-- 단건 상세 (summary + JOIN) -->
  <select id="getVehicleTripInfo" parameterType="map" resultType="map">
    SELECT
      vts.trip_id, vts.user_id, vts.vehicle_id,
      vts.departure, vts.arrival, vts.departure_name, vts.destination_name,
      vts.start_time, vts.end_time, vts.status,
      vts.total_distance, vts.duration_minutes, vts.location_count,
      vts.company_code,
      ui.user_name, v.vehicle_number

    FROM vehicle_trip_summary vts
    LEFT JOIN user_info ui ON vts.user_id = ui.user_id
    LEFT JOIN vehicles v ON vts.vehicle_id = v.id

    WHERE vts.trip_id = #{trip_id}
      AND (vts.company_code = #{company_code} OR vts.company_code = '*')
  </select>

  <!-- 경로(위치 이력) 조회 -->
  <select id="getVehicleTripRouteList" parameterType="map" resultType="map">
    SELECT
      id, latitude, longitude, accuracy, speed,
      distance_from_prev, trip_status, recorded_at

    FROM vehicle_location_history

    WHERE trip_id = #{trip_id}
      AND (company_code = #{company_code} OR company_code = '*')

    ORDER BY recorded_at ASC
  </select>

  <!-- 활성 운행 by tripId (endTrip / addLocation 등에서 사용) -->
  <select id="getVehicleTripActiveInfo" parameterType="map" resultType="map">
    SELECT *

    FROM vehicle_trip_summary

    WHERE trip_id = #{trip_id}
      AND (company_code = #{company_code} OR company_code = '*')
      AND status = 'active'
  </select>

  <!-- 활성 운행 by userId (getActiveTrip 엔드포인트) -->
  <select id="getVehicleTripActiveByUser" parameterType="map" resultType="map">
    SELECT *

    FROM vehicle_trip_summary

    WHERE user_id = #{user_id}
      AND (company_code = #{company_code} OR company_code = '*')
      AND status = 'active'

    ORDER BY start_time DESC
    LIMIT 1
  </select>

  <!-- 이전 위치 조회 (거리 계산용) -->
  <select id="getVehicleTripLastLocation" parameterType="map" resultType="map">
    SELECT latitude, longitude

    FROM vehicle_location_history

    WHERE trip_id = #{trip_id}
      AND (company_code = #{company_code} OR company_code = '*')

    ORDER BY recorded_at DESC
    LIMIT 1
  </select>

  <!-- 전체 위치 목록 (거리 계산용) -->
  <select id="getVehicleTripLocationListAll" parameterType="map" resultType="map">
    SELECT latitude, longitude

    FROM vehicle_location_history

    WHERE trip_id = #{trip_id}
      AND (company_code = #{company_code} OR company_code = '*')

    ORDER BY recorded_at ASC
  </select>

  <!-- 운행 통계 (종료 시 duration 계산) -->
  <select id="getVehicleTripLocationStats" parameterType="map" resultType="map">
    SELECT
      COUNT(*) AS location_count,
      COALESCE(
        EXTRACT(EPOCH FROM (MAX(recorded_at) - MIN(recorded_at))) / 60,
        0
      ) AS duration_minutes

    FROM vehicle_location_history

    WHERE trip_id = #{trip_id}
      AND (company_code = #{company_code} OR company_code = '*')
  </select>

  <!-- ═══════════════════════════════════════════════════
       Mutations
       ═══════════════════════════════════════════════════ -->

  <!-- 운행 시작: vehicle_trip_summary INSERT -->
  <insert id="insertVehicleTrip" parameterType="map">
    INSERT INTO vehicle_trip_summary (
      trip_id, user_id, vehicle_id,
      departure, arrival, departure_name, destination_name,
      start_time, status, company_code
    ) VALUES (
      #{trip_id},
      #{user_id},
      #{vehicle_id, jdbcType=INTEGER},
      #{departure, jdbcType=VARCHAR},
      #{arrival, jdbcType=VARCHAR},
      #{departure_name, jdbcType=VARCHAR},
      #{destination_name, jdbcType=VARCHAR},
      NOW(), 'active', #{company_code}
    )
  </insert>

  <!-- 위치 기록: vehicle_location_history INSERT -->
  <insert id="insertVehicleTripLocation" parameterType="map" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO vehicle_location_history (
      trip_id, user_id, vehicle_id,
      latitude, longitude, accuracy, speed, distance_from_prev,
      trip_status, departure, arrival, departure_name, destination_name,
      recorded_at, company_code
    ) VALUES (
      #{trip_id},
      #{user_id},
      #{vehicle_id, jdbcType=INTEGER},
      #{latitude}, #{longitude},
      #{accuracy, jdbcType=DOUBLE},
      #{speed, jdbcType=DOUBLE},
      #{distance_from_prev, jdbcType=DOUBLE},
      #{trip_status},
      #{departure, jdbcType=VARCHAR},
      #{arrival, jdbcType=VARCHAR},
      #{departure_name, jdbcType=VARCHAR},
      #{destination_name, jdbcType=VARCHAR},
      NOW(), #{company_code}
    )
  </insert>

  <!-- 운행 종료: status=completed, 거리/시간/위치수 업데이트 -->
  <update id="updateVehicleTripEnd" parameterType="map">
    UPDATE vehicle_trip_summary

    SET
      end_time = NOW(),
      total_distance = #{total_distance},
      duration_minutes = #{duration_minutes},
      location_count = #{location_count},
      status = 'completed'

    WHERE trip_id = #{trip_id}
      AND (company_code = #{company_code} OR company_code = '*')
  </update>

  <!-- 운행 취소: status=cancelled -->
  <update id="updateVehicleTripCancel" parameterType="map">
    UPDATE vehicle_trip_summary

    SET
      status = 'cancelled',
      end_time = NOW()

    WHERE trip_id = #{trip_id}
      AND (company_code = #{company_code} OR company_code = '*')
      AND status = 'active'
  </update>

  <!-- 운행 삭제 -->
  <delete id="deleteVehicleTrip" parameterType="map">
    DELETE FROM vehicle_trip_summary

    WHERE trip_id = #{trip_id}
      AND (company_code = #{company_code} OR company_code = '*')
  </delete>

  <!-- 위치 수 증가 -->
  <update id="updateVehicleTripLocationCount" parameterType="map">
    UPDATE vehicle_trip_summary

    SET
      location_count = COALESCE(location_count, '0')::INT + 1

    WHERE trip_id = #{trip_id}
  </update>

  <!-- 인터페이스 메서드명 매핑 -->
  <insert id="insertVehicleTripSummary" parameterType="map">
    INSERT INTO vehicle_trip_summary (
      trip_id, user_id, vehicle_id,
      departure, arrival, departure_name, destination_name,
      start_time, status, company_code
    ) VALUES (
      #{trip_id},
      #{user_id},
      #{vehicle_id, jdbcType=INTEGER},
      #{departure, jdbcType=VARCHAR},
      #{arrival, jdbcType=VARCHAR},
      #{departure_name, jdbcType=VARCHAR},
      #{destination_name, jdbcType=VARCHAR},
      NOW(), 'active', #{company_code}
    )
  </insert>

  <select id="getVehicleTripSummaryByTripId" parameterType="map" resultType="map">
    SELECT *

    FROM vehicle_trip_summary

    WHERE trip_id = #{trip_id}
  </select>

  <select id="getActiveTripByUserId" parameterType="map" resultType="map">
    SELECT *

    FROM vehicle_trip_summary

    WHERE user_id = #{user_id}
      AND (company_code = #{company_code} OR company_code = '*')
      AND status = 'active'

    ORDER BY start_time DESC
    LIMIT 1
  </select>

  <update id="updateVehicleTripSummary" parameterType="map">
    UPDATE vehicle_trip_summary

    SET
      status           = COALESCE(#{status},          status),
      end_time         = COALESCE(#{end_time},          end_time),
      duration_minutes = COALESCE(#{duration_minutes}, duration_minutes),
      total_distance   = COALESCE(#{total_distance},   total_distance),
      location_count   = COALESCE(#{location_count},   location_count)

    WHERE trip_id = #{trip_id}
  </update>

  <update id="cancelVehicleTrip" parameterType="map">
    UPDATE vehicle_trip_summary

    SET
      status   = 'cancelled',
      end_time = NOW()

    WHERE trip_id = #{trip_id}
      AND (company_code = #{company_code} OR company_code = '*')
      AND status = 'active'
  </update>

  <!-- ═══════════════════════════════════════════════════
       Reports
       ═══════════════════════════════════════════════════ -->

  <!-- 일별 통계 (기본 최근 30일, service에서 기본값 설정) -->
  <select id="getVehicleTripDailyReport" parameterType="map" resultType="map">
    SELECT
      DATE(start_time) AS date,
      COUNT(*) AS trip_count,
      COUNT(CASE WHEN status = 'completed' THEN 1 END) AS completed_count,
      COUNT(CASE WHEN status = 'cancelled' THEN 1 END) AS cancelled_count,
      COALESCE(SUM(CASE WHEN status = 'completed' THEN total_distance ELSE 0 END), 0) AS total_distance,
      COALESCE(SUM(CASE WHEN status = 'completed' THEN duration_minutes ELSE 0 END), 0) AS total_duration,
      COALESCE(AVG(CASE WHEN status = 'completed' THEN total_distance END), 0) AS avg_distance,
      COALESCE(AVG(CASE WHEN status = 'completed' THEN duration_minutes END), 0) AS avg_duration

    FROM vehicle_trip_summary

    WHERE (company_code = #{company_code} OR company_code = '*')
      AND DATE(start_time) &gt;= #{start_date}::date
      AND DATE(start_time) &lt;= #{end_date}::date
      <if test="user_id != null and user_id != ''">
        AND user_id = #{user_id}
      </if>
      <if test="vehicle_id != null">
        AND vehicle_id = #{vehicle_id}
      </if>

    GROUP BY DATE(start_time)
    ORDER BY DATE(start_time) DESC
  </select>

  <!-- 주별 통계 -->
  <select id="getVehicleTripWeeklyReport" parameterType="map" resultType="map">
    SELECT
      EXTRACT(WEEK FROM start_time) AS week_number,
      MIN(DATE(start_time)) AS week_start,
      MAX(DATE(start_time)) AS week_end,
      COUNT(*) AS trip_count,
      COUNT(CASE WHEN status = 'completed' THEN 1 END) AS completed_count,
      COALESCE(SUM(CASE WHEN status = 'completed' THEN total_distance ELSE 0 END), 0) AS total_distance,
      COALESCE(SUM(CASE WHEN status = 'completed' THEN duration_minutes ELSE 0 END), 0) AS total_duration,
      COALESCE(AVG(CASE WHEN status = 'completed' THEN total_distance END), 0) AS avg_distance

    FROM vehicle_trip_summary

    WHERE (company_code = #{company_code} OR company_code = '*')
      AND EXTRACT(YEAR FROM start_time) = #{year}
      AND EXTRACT(MONTH FROM start_time) = #{month}
      <if test="user_id != null and user_id != ''">
        AND user_id = #{user_id}
      </if>
      <if test="vehicle_id != null">
        AND vehicle_id = #{vehicle_id}
      </if>

    GROUP BY EXTRACT(WEEK FROM start_time)
    ORDER BY week_number
  </select>

  <!-- 월별 통계 -->
  <select id="getVehicleTripMonthlyReport" parameterType="map" resultType="map">
    SELECT
      EXTRACT(MONTH FROM start_time) AS month,
      COUNT(*) AS trip_count,
      COUNT(CASE WHEN status = 'completed' THEN 1 END) AS completed_count,
      COUNT(CASE WHEN status = 'cancelled' THEN 1 END) AS cancelled_count,
      COALESCE(SUM(CASE WHEN status = 'completed' THEN total_distance ELSE 0 END), 0) AS total_distance,
      COALESCE(SUM(CASE WHEN status = 'completed' THEN duration_minutes ELSE 0 END), 0) AS total_duration,
      COALESCE(AVG(CASE WHEN status = 'completed' THEN total_distance END), 0) AS avg_distance,
      COALESCE(AVG(CASE WHEN status = 'completed' THEN duration_minutes END), 0) AS avg_duration,
      COUNT(DISTINCT user_id) AS driver_count

    FROM vehicle_trip_summary

    WHERE (company_code = #{company_code} OR company_code = '*')
      AND EXTRACT(YEAR FROM start_time) = #{year}
      <if test="user_id != null and user_id != ''">
        AND user_id = #{user_id}
      </if>
      <if test="vehicle_id != null">
        AND vehicle_id = #{vehicle_id}
      </if>

    GROUP BY EXTRACT(MONTH FROM start_time)
    ORDER BY month
  </select>

  <!-- 요약 통계 (period: today/week/month/year) -->
  <select id="getVehicleTripSummaryReport" parameterType="map" resultType="map">
    SELECT
      COUNT(*) AS total_trips,
      COUNT(CASE WHEN status = 'completed' THEN 1 END) AS completed_trips,
      COUNT(CASE WHEN status = 'active' THEN 1 END) AS active_trips,
      COUNT(CASE WHEN status = 'cancelled' THEN 1 END) AS cancelled_trips,
      COALESCE(SUM(CASE WHEN status = 'completed' THEN total_distance ELSE 0 END), 0) AS total_distance,
      COALESCE(SUM(CASE WHEN status = 'completed' THEN duration_minutes ELSE 0 END), 0) AS total_duration,
      COALESCE(AVG(CASE WHEN status = 'completed' THEN total_distance END), 0) AS avg_distance,
      COALESCE(AVG(CASE WHEN status = 'completed' THEN duration_minutes END), 0) AS avg_duration,
      COUNT(DISTINCT user_id) AS active_drivers

    FROM vehicle_trip_summary

    WHERE (company_code = #{company_code} OR company_code = '*')
    <choose>
      <when test='period != null and "week".equals(period)'>
        AND start_time &gt;= CURRENT_DATE - INTERVAL '7 days'
      </when>
      <when test='period != null and "month".equals(period)'>
        AND start_time &gt;= CURRENT_DATE - INTERVAL '30 days'
      </when>
      <when test='period != null and "year".equals(period)'>
        AND EXTRACT(YEAR FROM start_time) = EXTRACT(YEAR FROM CURRENT_DATE)
      </when>
      <otherwise>
        AND DATE(start_time) = CURRENT_DATE
      </otherwise>
    </choose>
  </select>

  <!-- 운전자별 통계 -->
  <select id="getVehicleTripDriverReport" parameterType="map" resultType="map">
    SELECT
      vts.user_id,
      ui.user_name,
      COUNT(*) AS trip_count,
      COUNT(CASE WHEN vts.status = 'completed' THEN 1 END) AS completed_count,
      COALESCE(SUM(CASE WHEN vts.status = 'completed' THEN vts.total_distance ELSE 0 END), 0) AS total_distance,
      COALESCE(SUM(CASE WHEN vts.status = 'completed' THEN vts.duration_minutes ELSE 0 END), 0) AS total_duration,
      COALESCE(AVG(CASE WHEN vts.status = 'completed' THEN vts.total_distance END), 0) AS avg_distance

    FROM vehicle_trip_summary vts
    LEFT JOIN user_info ui ON vts.user_id = ui.user_id

    WHERE (vts.company_code = #{company_code} OR vts.company_code = '*')
      <if test="start_date != null and start_date != ''">
        AND DATE(vts.start_time) &gt;= #{start_date}::date
      </if>
      <if test="end_date != null and end_date != ''">
        AND DATE(vts.start_time) &lt;= #{end_date}::date
      </if>

    GROUP BY vts.user_id, ui.user_name
    ORDER BY total_distance DESC
    LIMIT #{limit}
  </select>

  <!-- 구간별 통계 -->
  <select id="getVehicleTripRouteReport" parameterType="map" resultType="map">
    SELECT
      departure, arrival, departure_name, destination_name,
      COUNT(*) AS trip_count,
      COUNT(CASE WHEN status = 'completed' THEN 1 END) AS completed_count,
      COALESCE(SUM(CASE WHEN status = 'completed' THEN total_distance ELSE 0 END), 0) AS total_distance,
      COALESCE(AVG(CASE WHEN status = 'completed' THEN total_distance END), 0) AS avg_distance,
      COALESCE(AVG(CASE WHEN status = 'completed' THEN duration_minutes END), 0) AS avg_duration

    FROM vehicle_trip_summary

    WHERE (company_code = #{company_code} OR company_code = '*')
      AND departure IS NOT NULL
      AND arrival IS NOT NULL
      <if test="start_date != null and start_date != ''">
        AND DATE(start_time) &gt;= #{start_date}::date
      </if>
      <if test="end_date != null and end_date != ''">
        AND DATE(start_time) &lt;= #{end_date}::date
      </if>

    GROUP BY departure, arrival, departure_name, destination_name
    ORDER BY trip_count DESC
    LIMIT #{limit}
  </select>

</mapper>
