<?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="com.tasteby.mapper.VideoMapper">

    <!-- ===== Result Maps ===== -->

    <resultMap id="videoSummaryMap" type="VideoSummary">
        <id property="id" column="id"/>
        <result property="videoId" column="video_id"/>
        <result property="title" column="title"/>
        <result property="url" column="url"/>
        <result property="status" column="status"/>
        <result property="publishedAt" column="published_at"/>
        <result property="channelName" column="channel_name"/>
        <result property="hasTranscript" column="has_transcript"/>
        <result property="hasLlm" column="has_llm"/>
        <result property="restaurantCount" column="restaurant_count"/>
        <result property="matchedCount" column="matched_count"/>
    </resultMap>

    <resultMap id="videoDetailMap" type="VideoDetail">
        <id property="id" column="id"/>
        <result property="videoId" column="video_id"/>
        <result property="title" column="title"/>
        <result property="url" column="url"/>
        <result property="status" column="status"/>
        <result property="publishedAt" column="published_at"/>
        <result property="channelName" column="channel_name"/>
        <result property="transcriptText" column="transcript_text"
                typeHandler="com.tasteby.config.ClobTypeHandler"/>
    </resultMap>

    <resultMap id="videoRestaurantLinkMap" type="VideoRestaurantLink">
        <result property="restaurantId" column="id"/>
        <result property="name" column="name"/>
        <result property="address" column="address"/>
        <result property="cuisineType" column="cuisine_type"/>
        <result property="priceRange" column="price_range"/>
        <result property="region" column="region"/>
        <result property="foodsMentioned" column="foods_mentioned"
                typeHandler="com.tasteby.config.ClobTypeHandler"/>
        <result property="evaluation" column="evaluation"
                typeHandler="com.tasteby.config.ClobTypeHandler"/>
        <result property="guests" column="guests"
                typeHandler="com.tasteby.config.ClobTypeHandler"/>
        <result property="googlePlaceId" column="google_place_id"/>
        <result property="latitude" column="latitude"/>
        <result property="longitude" column="longitude"/>
    </resultMap>

    <!-- ===== Queries ===== -->

    <select id="findAll" resultMap="videoSummaryMap">
        SELECT v.id, v.video_id, v.title, v.url, v.status,
               v.published_at, c.channel_name,
               CASE WHEN v.transcript_text IS NOT NULL AND dbms_lob.getlength(v.transcript_text) &gt; 0 THEN 1 ELSE 0 END AS has_transcript,
               CASE WHEN v.llm_raw_response IS NOT NULL AND dbms_lob.getlength(v.llm_raw_response) &gt; 0 THEN 1 ELSE 0 END AS has_llm,
               (SELECT COUNT(*) FROM video_restaurants vr WHERE vr.video_id = v.id) AS restaurant_count,
               (SELECT COUNT(*) FROM video_restaurants vr JOIN restaurants r ON r.id = vr.restaurant_id
                WHERE vr.video_id = v.id AND r.google_place_id IS NOT NULL) AS matched_count
        FROM videos v
        JOIN channels c ON c.id = v.channel_id
        <if test="status != null and status != ''">
            WHERE v.status = #{status}
        </if>
        ORDER BY v.published_at DESC NULLS LAST
    </select>

    <select id="findDetail" resultMap="videoDetailMap">
        SELECT v.id, v.video_id, v.title, v.url, v.status,
               v.published_at, v.transcript_text, c.channel_name
        FROM videos v
        JOIN channels c ON c.id = v.channel_id
        WHERE v.id = #{id}
    </select>

    <select id="findVideoRestaurants" resultMap="videoRestaurantLinkMap">
        SELECT r.id, r.name, r.address, r.cuisine_type, r.price_range, r.region,
               vr.foods_mentioned, vr.evaluation, vr.guests,
               r.google_place_id, r.latitude, r.longitude
        FROM video_restaurants vr
        JOIN restaurants r ON r.id = vr.restaurant_id
        WHERE vr.video_id = #{videoId}
    </select>

    <!-- ===== Updates ===== -->

    <update id="updateStatus">
        UPDATE videos SET status = #{status} WHERE id = #{id}
    </update>

    <update id="updateTitle">
        UPDATE videos SET title = #{title} WHERE id = #{id}
    </update>

    <update id="updateTranscript">
        UPDATE videos SET transcript_text = #{transcript} WHERE id = #{id}
    </update>

    <update id="updateVideoFields">
        UPDATE videos SET
            status = #{status},
            processed_at = SYSTIMESTAMP
            <if test="transcript != null">
                , transcript_text = #{transcript}
            </if>
            <if test="llmResponse != null">
                , llm_raw_response = #{llmResponse}
            </if>
        WHERE id = #{id}
    </update>

    <!-- ===== Cascade deletes for video deletion ===== -->

    <delete id="deleteVectorsByVideoOnly">
        DELETE FROM restaurant_vectors WHERE restaurant_id IN (
            SELECT vr.restaurant_id FROM video_restaurants vr
            WHERE vr.video_id = #{videoId}
            AND NOT EXISTS (SELECT 1 FROM video_restaurants vr2
                WHERE vr2.restaurant_id = vr.restaurant_id AND vr2.video_id != #{videoId})
        )
    </delete>

    <delete id="deleteReviewsByVideoOnly">
        DELETE FROM user_reviews WHERE restaurant_id IN (
            SELECT vr.restaurant_id FROM video_restaurants vr
            WHERE vr.video_id = #{videoId}
            AND NOT EXISTS (SELECT 1 FROM video_restaurants vr2
                WHERE vr2.restaurant_id = vr.restaurant_id AND vr2.video_id != #{videoId})
        )
    </delete>

    <delete id="deleteFavoritesByVideoOnly">
        DELETE FROM user_favorites WHERE restaurant_id IN (
            SELECT vr.restaurant_id FROM video_restaurants vr
            WHERE vr.video_id = #{videoId}
            AND NOT EXISTS (SELECT 1 FROM video_restaurants vr2
                WHERE vr2.restaurant_id = vr.restaurant_id AND vr2.video_id != #{videoId})
        )
    </delete>

    <delete id="deleteRestaurantsByVideoOnly">
        DELETE FROM restaurants WHERE id IN (
            SELECT vr.restaurant_id FROM video_restaurants vr
            WHERE vr.video_id = #{videoId}
            AND NOT EXISTS (SELECT 1 FROM video_restaurants vr2
                WHERE vr2.restaurant_id = vr.restaurant_id AND vr2.video_id != #{videoId})
        )
    </delete>

    <delete id="deleteVideoRestaurants">
        DELETE FROM video_restaurants WHERE video_id = #{videoId}
    </delete>

    <delete id="deleteVideo">
        DELETE FROM videos WHERE id = #{videoId}
    </delete>

    <!-- ===== Single video-restaurant unlink + orphan cleanup ===== -->

    <delete id="deleteOneVideoRestaurant">
        DELETE FROM video_restaurants WHERE video_id = #{videoId} AND restaurant_id = #{restaurantId}
    </delete>

    <delete id="cleanupOrphanVectors">
        DELETE FROM restaurant_vectors WHERE restaurant_id = #{restaurantId}
        AND NOT EXISTS (SELECT 1 FROM video_restaurants WHERE restaurant_id = #{restaurantId})
    </delete>

    <delete id="cleanupOrphanReviews">
        DELETE FROM user_reviews WHERE restaurant_id = #{restaurantId}
        AND NOT EXISTS (SELECT 1 FROM video_restaurants WHERE restaurant_id = #{restaurantId})
    </delete>

    <delete id="cleanupOrphanFavorites">
        DELETE FROM user_favorites WHERE restaurant_id = #{restaurantId}
        AND NOT EXISTS (SELECT 1 FROM video_restaurants WHERE restaurant_id = #{restaurantId})
    </delete>

    <delete id="cleanupOrphanRestaurant">
        DELETE FROM restaurants WHERE id = #{restaurantId}
        AND NOT EXISTS (SELECT 1 FROM video_restaurants WHERE restaurant_id = #{restaurantId})
    </delete>

    <!-- ===== Insert / Lookup ===== -->

    <insert id="insertVideo">
        INSERT INTO videos (id, channel_id, video_id, title, url, published_at)
        VALUES (#{id}, #{channelId}, #{videoId}, #{title}, #{url},
                TO_TIMESTAMP(#{publishedAt}, 'YYYY-MM-DD"T"HH24:MI:SS"Z"'))
    </insert>

    <select id="getExistingVideoIds" resultType="string">
        SELECT video_id FROM videos WHERE channel_id = #{channelId}
    </select>

    <select id="getLatestVideoDate" resultType="string">
        SELECT TO_CHAR(MAX(published_at), 'YYYY-MM-DD"T"HH24:MI:SS"Z"') AS latest_date
        FROM videos WHERE channel_id = #{channelId}
    </select>

    <!-- ===== Pipeline queries ===== -->

    <select id="findPendingVideos" resultType="map">
        SELECT id, video_id, title, url FROM videos
        WHERE status = 'pending' ORDER BY created_at
        FETCH FIRST #{limit} ROWS ONLY
    </select>

    <select id="findVideosForBulkExtract" resultType="map">
        SELECT v.id, v.video_id, v.title, v.url, v.transcript_text
        FROM videos v
        WHERE v.transcript_text IS NOT NULL
          AND dbms_lob.getlength(v.transcript_text) &gt; 0
          AND (v.llm_raw_response IS NULL OR dbms_lob.getlength(v.llm_raw_response) = 0)
          AND v.status != 'skip'
        ORDER BY v.published_at DESC
    </select>

    <select id="findVideosWithoutTranscript" resultType="map">
        SELECT id, video_id, title, url
        FROM videos
        WHERE (transcript_text IS NULL OR dbms_lob.getlength(transcript_text) = 0)
          AND status NOT IN ('skip', 'no_transcript')
        ORDER BY created_at
    </select>

    <select id="findVideosByIds" resultType="map">
        SELECT id, video_id, title, url
        FROM videos
        WHERE id IN
        <foreach item="id" collection="ids" open="(" separator="," close=")">
            #{id}
        </foreach>
        ORDER BY created_at
    </select>

    <select id="findVideosForExtractByIds" resultType="map">
        SELECT v.id, v.video_id, v.title, v.url, v.transcript_text
        FROM videos v
        WHERE v.id IN
        <foreach item="id" collection="ids" open="(" separator="," close=")">
            #{id}
        </foreach>
        ORDER BY v.published_at DESC
    </select>

    <update id="updateVideoRestaurantFields">
        UPDATE video_restaurants
        SET foods_mentioned = #{foodsJson,jdbcType=CLOB},
            evaluation = #{evaluation,jdbcType=CLOB},
            guests = #{guestsJson,jdbcType=CLOB}
        WHERE video_id = #{videoId} AND restaurant_id = #{restaurantId}
    </update>

</mapper>
