<?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.zcloud.personnel.positioning.persistence.mapper.FenceMapper">
    <sql id="mappedCompanyJoin">
        LEFT JOIN (
            SELECT local_corpinfo_id, MAX(local_corpinfo_name) AS local_corpinfo_name
            FROM org_match
            WHERE match_status = 'MATCHED'
              AND (delete_enum IS NULL OR delete_enum = 'FALSE')
              AND local_corpinfo_id IS NOT NULL AND local_corpinfo_id != ''
            GROUP BY local_corpinfo_id
        ) mapped_org ON mapped_org.local_corpinfo_id = CAST(f.corpinfo_id AS CHAR)
        LEFT JOIN corp_info corp_uuid
            ON mapped_org.local_corpinfo_id IS NULL
           AND CAST(corp_uuid.corpinfo_id AS CHAR) = CAST(f.corpinfo_id AS CHAR)
           AND (corp_uuid.delete_enum IS NULL OR corp_uuid.delete_enum = 'FALSE')
        LEFT JOIN corp_info corp_internal
            ON mapped_org.local_corpinfo_id IS NULL
           AND corp_uuid.corpinfo_id IS NULL
           AND CAST(corp_internal.id AS CHAR) = CAST(f.corpinfo_id AS CHAR)
           AND (corp_internal.delete_enum IS NULL OR corp_internal.delete_enum = 'FALSE')
    </sql>

    <sql id="mappedCompanyId">
        COALESCE(mapped_org.local_corpinfo_id, CAST(corp_uuid.corpinfo_id AS CHAR),
                 CAST(corp_internal.corpinfo_id AS CHAR))
    </sql>

    <sql id="mappedCompanyName">
        COALESCE(mapped_org.local_corpinfo_name, corp_uuid.corp_name, corp_internal.corp_name)
    </sql>

    <select id="listFences"
            resultType="com.zcloud.personnel.positioning.persistence.dataobject.FenceDO">
        SELECT f.id, f.fence_code, f.fence_name, f.fence_scope, f.fence_biz_name,
               <include refid="mappedCompanyId"/> AS corpinfo_id,
               <include refid="mappedCompanyName"/> AS corpinfo_name,
               f.org_code, f.org_name, f.area_id, f.area_name, f.coor, f.space_type,
               f.building_id, f.floor, f.polygon_json, f.center_lon, f.center_lat,
               f.silence, f.effect_start, f.effect_end, f.effect_period_json, f.status,
               f.finds_fence_id, f.finds_fence_code, f.sync_status, f.sync_token,
               f.last_sync_time, f.raw_json, f.delete_enum, f.remarks, f.create_name,
               f.update_name, f.tenant_id, f.org_id, f.env, f.version, f.create_time,
               f.update_time, f.create_id, f.update_id
        FROM fence f
        <include refid="mappedCompanyJoin"/>
        WHERE (f.delete_enum IS NULL OR f.delete_enum = 'FALSE')
          AND <include refid="mappedCompanyId"/> IS NOT NULL
        <if test="params.eqId != null">AND f.id = #{params.eqId}</if>
        <if test="params.eqFenceCode != null and params.eqFenceCode != ''">
            AND f.fence_code = #{params.eqFenceCode}
        </if>
        <if test="params.electronicFenceOnly == true">
            AND f.fence_scope IN ('ELECTRONIC', 'WORK_AREA')
        </if>
        <if test="params.eqFenceScope != null and params.eqFenceScope != ''">
            AND f.fence_scope = #{params.eqFenceScope}
        </if>
        <if test="params.eqCorpinfoId != null and params.eqCorpinfoId != ''">
            AND <include refid="mappedCompanyId"/> = #{params.eqCorpinfoId}
        </if>
        <if test="params.eqCorpinfoName != null and params.eqCorpinfoName != ''">
            AND <include refid="mappedCompanyName"/> = #{params.eqCorpinfoName}
        </if>
        <if test="params.likeCorpinfoName != null and params.likeCorpinfoName != ''">
            AND <include refid="mappedCompanyName"/> LIKE CONCAT('%', #{params.likeCorpinfoName}, '%')
        </if>
        <if test="params.likeFenceName != null and params.likeFenceName != ''">
            AND f.fence_name LIKE CONCAT('%', #{params.likeFenceName}, '%')
        </if>
        <if test="params.likeFenceBizName != null and params.likeFenceBizName != ''">
            AND f.fence_biz_name LIKE CONCAT('%', #{params.likeFenceBizName}, '%')
        </if>
        <if test="params.eqOrgCode != null and params.eqOrgCode != ''">
            AND f.org_code = #{params.eqOrgCode}
        </if>
        <if test="params.likeOrgName != null and params.likeOrgName != ''">
            AND f.org_name LIKE CONCAT('%', #{params.likeOrgName}, '%')
        </if>
        <if test="params.eqStatus != null and params.eqStatus != ''">
            AND f.status = #{params.eqStatus}
        </if>
        <if test="params.eqAreaId != null">
            AND f.area_id = #{params.eqAreaId}
        </if>
        <if test="params.likeAreaName != null and params.likeAreaName != ''">
            AND f.area_name LIKE CONCAT('%', #{params.likeAreaName}, '%')
        </if>
        <if test="params.eqCoor != null and params.eqCoor != ''">AND f.coor = #{params.eqCoor}</if>
        <if test="params.eqSpaceType != null and params.eqSpaceType != ''">
            AND f.space_type = #{params.eqSpaceType}
        </if>
        <if test="params.eqBuildingId != null">AND f.building_id = #{params.eqBuildingId}</if>
        <if test="params.eqFloor != null">AND f.floor = #{params.eqFloor}</if>
        <if test="params.eqSilence != null">AND f.silence = #{params.eqSilence}</if>
        <if test="params.geEffectStart != null">AND f.effect_start &gt;= #{params.geEffectStart}</if>
        <if test="params.leEffectStart != null">AND f.effect_start &lt;= #{params.leEffectStart}</if>
        <if test="params.geEffectEnd != null">AND f.effect_end &gt;= #{params.geEffectEnd}</if>
        <if test="params.leEffectEnd != null">AND f.effect_end &lt;= #{params.leEffectEnd}</if>
        <if test="params.eqFindsFenceId != null">AND f.finds_fence_id = #{params.eqFindsFenceId}</if>
        <if test="params.eqFindsFenceCode != null and params.eqFindsFenceCode != ''">
            AND f.finds_fence_code = #{params.eqFindsFenceCode}
        </if>
        <if test="params.eqSyncStatus != null and params.eqSyncStatus != ''">
            AND f.sync_status = #{params.eqSyncStatus}
        </if>
        <if test="params.geLastSyncTime != null">AND f.last_sync_time &gt;= #{params.geLastSyncTime}</if>
        <if test="params.leLastSyncTime != null">AND f.last_sync_time &lt;= #{params.leLastSyncTime}</if>
        ORDER BY f.create_time DESC, f.id DESC
    </select>

    <select id="listCompanyStats"
            resultType="com.zcloud.personnel.positioning.persistence.dataobject.FenceCompanyStatDO">
        SELECT <include refid="mappedCompanyId"/> AS corpinfo_id,
               <include refid="mappedCompanyName"/> AS corpinfo_name,
               COUNT(1) AS fence_count,
               SUM(CASE WHEN f.status = 'ENABLED' THEN 1 ELSE 0 END) AS enabled_count,
               COALESCE(MAX(f.last_sync_time), MAX(f.update_time)) AS last_sync_time
        FROM fence f
        <include refid="mappedCompanyJoin"/>
        WHERE f.delete_enum = 'FALSE'
          AND f.fence_scope IN ('ELECTRONIC', 'WORK_AREA')
          AND <include refid="mappedCompanyId"/> IS NOT NULL
        <if test="params.eqCorpinfoId != null and params.eqCorpinfoId != ''">
            AND <include refid="mappedCompanyId"/> = #{params.eqCorpinfoId}
        </if>
        <if test="params.likeCorpinfoName != null and params.likeCorpinfoName != ''">
            AND <include refid="mappedCompanyName"/> LIKE CONCAT('%', #{params.likeCorpinfoName}, '%')
        </if>
        GROUP BY <include refid="mappedCompanyId"/>, <include refid="mappedCompanyName"/>
        ORDER BY COALESCE(MAX(f.last_sync_time), MAX(f.update_time)) DESC
    </select>

    <select id="listCompanyOptions"
            resultType="com.zcloud.personnel.positioning.persistence.dataobject.CompanyOptionDO">
        SELECT MAX(company_name) AS label, company_id AS value
        FROM (
            SELECT local_corpinfo_name AS company_name, local_corpinfo_id AS company_id,
                   NULL AS credit_code, NULL AS contacts, NULL AS legal_representative
            FROM org_match
            WHERE match_status = 'MATCHED'
              AND (delete_enum IS NULL OR delete_enum = 'FALSE')
              AND local_corpinfo_id IS NOT NULL AND local_corpinfo_id != ''
              AND local_corpinfo_name IS NOT NULL AND local_corpinfo_name != ''
            UNION ALL
            SELECT corp_name, CAST(corpinfo_id AS CHAR), code, contacts, lr_name
            FROM corp_info
            WHERE (delete_enum IS NULL OR delete_enum = 'FALSE')
              AND corpinfo_id IS NOT NULL AND corp_name IS NOT NULL
        ) platform_company
        WHERE 1 = 1
        <if test="params.eqCorpinfoId != null and params.eqCorpinfoId != ''">
            AND company_id = #{params.eqCorpinfoId}
        </if>
        <if test="params.keyword != null and params.keyword != ''">
            AND (company_name LIKE CONCAT('%', #{params.keyword}, '%')
                OR credit_code LIKE CONCAT('%', #{params.keyword}, '%')
                OR contacts LIKE CONCAT('%', #{params.keyword}, '%')
                OR legal_representative LIKE CONCAT('%', #{params.keyword}, '%'))
        </if>
        GROUP BY company_id
        ORDER BY label ASC
        LIMIT 200
    </select>

    <update id="clearAreaLink">
        UPDATE fence SET area_id = NULL, area_name = NULL WHERE area_id = #{areaId}
    </update>

</mapper>
