Bridge.Database.AfterMigration("sky_phone", function()
SkyPhoneCompanies = {}

local definitions = {}
local definition_ids = {}
local definitions_by_job = {}
local service_lines_by_number = {}
local call_availability = {}
local round_robin_positions = {}
local member_tokens = {}
local terminal_statuses = {
    completed = true,
    cancelled = true,
}
local status_transitions = {
    new = { cancelled = true },
    assigned = { in_progress = true, cancelled = true },
    in_progress = { waiting_customer = true, completed = true, cancelled = true },
    waiting_customer = { in_progress = true, cancelled = true },
}

local function uuid()
    local rows = Bridge.Database.Query("SELECT UUID() AS `id`", {})
    if not rows[1] or type(rows[1].id) ~= "string" then
        error("[sky_phone] Database did not generate a Companies UUID.")
    end
    return rows[1].id
end

local function trim(value)
    if type(value) ~= "string" then
        return nil
    end
    return value:match("^%s*(.-)%s*$")
end

local function valid_text(value, maximum, allow_empty)
    local text = trim(value)
    if not text or text:find("%z") then
        return nil
    end
    local length = utf8.len(text)
    if not length or length > maximum or (not allow_empty and length == 0) then
        return nil
    end
    return text
end

local function valid_integer(value, minimum, maximum)
    local number = tonumber(value)
    if not number or number ~= number or number < minimum or number > maximum
        or number ~= math.floor(number)
    then
        return nil
    end
    return number
end

local function valid_uuid(value)
    return type(value) == "string"
        and value:match("^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$") ~= nil
end

local function valid_service_id(value)
    return type(value) == "string"
        and #value >= 1
        and #value <= 64
        and value:match("^[%w_-]+$") ~= nil
end

local function valid_array(value, maximum)
    if type(value) ~= "table" or #value > maximum then
        return false
    end
    local count = 0
    for key in pairs(value) do
        if type(key) ~= "number" or key < 1 or key ~= math.floor(key) or key > #value then
            return false
        end
        count = count + 1
    end
    return count == #value
end

local function iso_time(value)
    local seconds = tonumber(value)
    if not seconds or seconds <= 0 then
        return nil
    end
    return os.date("!%Y-%m-%dT%H:%M:%SZ", seconds)
end

local function days_from_civil(year, month, day)
    year = year - (month <= 2 and 1 or 0)
    local era = math.floor(year / 400)
    local year_of_era = year - era * 400
    local adjusted_month = month + (month > 2 and -3 or 9)
    local day_of_year = math.floor((153 * adjusted_month + 2) / 5) + day - 1
    local day_of_era = year_of_era * 365 + math.floor(year_of_era / 4)
        - math.floor(year_of_era / 100) + day_of_year
    return era * 146097 + day_of_era - 719468
end

local function utc_epoch(year, month, day, hour, minute, second)
    if year < 1970 or year > 2100 or month < 1 or month > 12
        or day < 1 or hour < 0 or hour > 23 or minute < 0 or minute > 59
        or second < 0 or second > 59
    then
        return nil
    end
    local month_lengths = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    if year % 400 == 0 or (year % 4 == 0 and year % 100 ~= 0) then
        month_lengths[2] = 29
    end
    if day > month_lengths[month] then
        return nil
    end
    return days_from_civil(year, month, day) * 86400 + hour * 3600 + minute * 60 + second
end

local function parse_expiry(value, maximum_seconds)
    if value == nil or value == "" then
        return nil
    end
    if type(value) ~= "string" or #value > 40 then
        return false
    end
    local year, month, day, hour, minute, second = value:match(
        "^(%d%d%d%d)%-(%d%d)%-(%d%d)T(%d%d):(%d%d):(%d%d)Z$"
    )
    if not year then
        year, month, day, hour, minute, second = value:match(
            "^(%d%d%d%d)%-(%d%d)%-(%d%d)T(%d%d):(%d%d):(%d%d)%.%d+Z$"
        )
    end
    if not year then
        return false
    end
    local epoch = utc_epoch(
        tonumber(year),
        tonumber(month),
        tonumber(day),
        tonumber(hour),
        tonumber(minute),
        tonumber(second)
    )
    local now = os.time()
    if not epoch or epoch <= now or epoch - now > maximum_seconds then
        return false
    end
    return epoch
end

local function permission_grade(definition, permission)
    local grade = definition.Permissions and tonumber(definition.Permissions[permission])
    return grade and math.max(0, math.floor(grade)) or nil
end

local function validate_configuration()
    if type(Config.Companies) ~= "table" or type(Config.Companies.Definitions) ~= "table" then
        error("[sky_phone] Config.Companies.Definitions must be configured.")
    end
    if type(Config.Companies.Enabled) ~= "boolean" then
        error("[sky_phone] Config.Companies.Enabled must be a boolean.")
    end
    for _, field in ipairs({
        { "PageSize", 1000 },
        { "MaximumPageSize", 1000 },
        { "MaximumOpenRequestsPerSim", 1000 },
        { "MaximumServices", 255 },
        { "MaximumRequestMedia", 255 },
        { "SubjectMaxLength", 120 },
        { "RequestBodyMaxLength", 2000 },
        { "MessageMaxLength", 2000 },
        { "ProfileDescriptionMaxLength", 1000 },
        { "DistrictMaxLength", 80 },
        { "AddressMaxLength", 160 },
        { "ServiceTitleMaxLength", 80 },
        { "ServiceDescriptionMaxLength", 500 },
        { "ServicePriceMaxLength", 80 },
        { "AnnouncementTitleMaxLength", 120 },
        { "AnnouncementBodyMaxLength", 1000 },
        { "AvailabilityMaximumSeconds", 31536000 },
        { "AnnouncementMaximumSeconds", 31536000 },
        { "RetentionDays", 36500 },
    }) do
        if not valid_integer(Config.Companies[field[1]], 1, field[2]) then
            error(("[sky_phone] Config.Companies.%s is outside its supported range."):format(field[1]))
        end
    end
    if Config.Companies.PageSize > Config.Companies.MaximumPageSize then
        error("[sky_phone] Companies PageSize cannot exceed MaximumPageSize.")
    end
    if type(Config.Companies.RateLimits) ~= "table" then
        error("[sky_phone] Config.Companies.RateLimits must be configured.")
    end
    for _, name in ipairs({ "Read", "Search", "CreateRequest", "Message", "RequestAction", "Profile", "CallAvailability" }) do
        if not valid_integer(Config.Companies.RateLimits[name], 1, 100000) then
            error(("[sky_phone] Companies rate limit '%s' is invalid."):format(name))
        end
    end
    if type(Config.Companies.CallRouting) ~= "table"
        or not valid_integer(Config.Companies.CallRouting.MaxAttempts, 1, 20)
        or not valid_integer(Config.Companies.CallRouting.RingSeconds, 1, 120)
    then
        error("[sky_phone] Config.Companies.CallRouting is invalid.")
    end
    local configured_statuses = {
        new = true,
        assigned = true,
        in_progress = true,
        waiting_customer = true,
        completed = true,
        cancelled = true,
    }
    if type(Config.Companies.Statuses) ~= "table" then
        error("[sky_phone] Config.Companies.Statuses must be configured.")
    end
    for status in pairs(configured_statuses) do
        if Config.Companies.Statuses[status] ~= true then
            error(("[sky_phone] Companies status '%s' must be enabled."):format(status))
        end
    end
    for status, enabled in pairs(Config.Companies.Statuses) do
        if not configured_statuses[status] or enabled ~= true then
            error(("[sky_phone] Companies status '%s' is unsupported."):format(tostring(status)))
        end
    end
    if type(Config.Companies.AvailabilityStatuses) ~= "table" then
        error("[sky_phone] Config.Companies.AvailabilityStatuses must be configured.")
    end
    local configured_availability = { available = true, busy = true, closed = true }
    for _, status in ipairs({ "available", "busy", "closed" }) do
        if Config.Companies.AvailabilityStatuses[status] ~= true then
            error(("[sky_phone] Companies availability status '%s' must be enabled."):format(status))
        end
    end
    for status, enabled in pairs(Config.Companies.AvailabilityStatuses) do
        if not configured_availability[status] or enabled ~= true then
            error(("[sky_phone] Companies availability status '%s' is unsupported."):format(tostring(status)))
        end
    end
    if not valid_array(Config.Companies.Categories, 100) then
        error("[sky_phone] Config.Companies.Categories must be a bounded array.")
    end
    local category_ids = {}
    local configured_service_ids = {}
    for _, category_id in ipairs(Config.Companies.Categories) do
        if type(category_id) ~= "string" or #category_id > 64
            or not category_id:match("^[a-z0-9_-]+$") or category_ids[category_id]
        then
            error("[sky_phone] Companies contains an invalid category ID.")
        end
        category_ids[category_id] = true
    end

    for company_id, definition in pairs(Config.Companies.Definitions) do
        if type(company_id) ~= "string" or #company_id > 64 or not company_id:match("^[a-z0-9_-]+$")
            or type(definition) ~= "table"
            or type(definition.Job) ~= "string" or #definition.Job > 64
            or not definition.Job:match("^[%w_-]+$")
            or not valid_text(definition.Name, 120, false)
            or not category_ids[definition.Category]
        then
            error(("[sky_phone] Company definition '%s' is invalid."):format(tostring(company_id)))
        end
        local description = valid_text(definition.Description or "", Config.Companies.ProfileDescriptionMaxLength, true)
        local district = valid_text(definition.District or "", Config.Companies.DistrictMaxLength, true)
        local location_label = valid_text(
            definition.LocationLabel or definition.Address or "",
            Config.Companies.DistrictMaxLength,
            true
        )
        local address = valid_text(definition.Address or "", Config.Companies.AddressMaxLength, true)
        local logo_url = valid_text(definition.LogoUrl, 2048, false)
        if not description or not district or not location_label or not address
            or type(definition.Public) ~= "boolean" or type(definition.Emergency) ~= "boolean"
            or type(definition.Verified) ~= "boolean" or type(definition.AcceptsRequests) ~= "boolean"
            or not Config.Companies.AvailabilityStatuses[definition.DefaultAvailability]
            or not valid_text(definition.Icon, 64, false)
            or not logo_url or not logo_url:match("^https://[^%s]+$")
            or (definition.Emergency and definition.AcceptsRequests)
        then
            error(("[sky_phone] Company definition '%s' has invalid public profile defaults."):format(company_id))
        end
        definition.Name = trim(definition.Name)
        definition.Description = description
        definition.District = district
        definition.LocationLabel = location_label
        definition.Address = address
        definition.LogoUrl = logo_url
        if definition.Location ~= nil then
            local location_type = type(definition.Location)
            if location_type ~= "table" and location_type ~= "vector3" then
                error(("[sky_phone] Company definition '%s' has invalid location coordinates."):format(company_id))
            end
            local x = tonumber(definition.Location.x)
            local y = tonumber(definition.Location.y)
            local z = tonumber(definition.Location.z)
            if not x or not y or not z or x ~= x or y ~= y or z ~= z
                or math.abs(x) > 10000 or math.abs(y) > 10000 or math.abs(z) > 2000
            then
                error(("[sky_phone] Company definition '%s' has invalid location coordinates."):format(company_id))
            end
        end
        if definitions_by_job[definition.Job] then
            error(("[sky_phone] Framework job '%s' is assigned to more than one company."):format(definition.Job))
        end
        local line = definition.ServiceLine
        if type(line) ~= "table" then
            error(("[sky_phone] Company '%s' has no service line configuration."):format(company_id))
        end
        local number = SkyPhoneSimNumber.NormalizeService(line.Number, Config.Sim.NumberLength)
        if not number then
            error(("[sky_phone] Company '%s' has an invalid service number."):format(company_id))
        end
        if service_lines_by_number[number] then
            error(("[sky_phone] Service number '%s' is assigned more than once."):format(number))
        end
        if type(line.AutoContact) ~= "boolean" or type(line.CanCall) ~= "boolean"
            or type(line.CanMessage) ~= "boolean"
            or not valid_integer(line.MinimumGrade, 0, 10000)
        then
            error(("[sky_phone] Company '%s' has invalid service line flags or grade."):format(company_id))
        end
        if line.AutoContact and not definition.Public then
            error(("[sky_phone] Private company '%s' cannot create a public system contact."):format(company_id))
        end
        if line.Routing ~= "round_robin" then
            error(("[sky_phone] Company '%s' uses unsupported call routing '%s'."):format(company_id, tostring(line.Routing)))
        end
        if line.CanMessage then
            error(("[sky_phone] Company '%s' enables messaging without a virtual service-line message router."):format(company_id))
        end
        line.Number = number
        definitions[company_id] = definition
        definition_ids[#definition_ids + 1] = company_id
        definitions_by_job[definition.Job] = company_id
        service_lines_by_number[number] = company_id
        for _, permission in ipairs({ "WorkQueue", "Availability", "Assign", "Profile", "Hours", "Services", "Announcement" }) do
            if not definition.Permissions or not valid_integer(definition.Permissions[permission], 0, 10000) then
                error(("[sky_phone] Company '%s' has no valid '%s' grade."):format(company_id, permission))
            end
        end
        local default_services = definition.Services
        if default_services == nil then
            default_services = {}
            definition.Services = default_services
        end
        if not valid_array(default_services, Config.Companies.MaximumServices) then
            error(("[sky_phone] Company '%s' has an invalid default service list."):format(company_id))
        end
        for _, service in ipairs(default_services) do
            if type(service) ~= "table" then
                error(("[sky_phone] Company '%s' has an invalid default service."):format(company_id))
            end
            local title = valid_text(service.Title, Config.Companies.ServiceTitleMaxLength, false)
            local service_description = valid_text(
                service.Description or "",
                Config.Companies.ServiceDescriptionMaxLength,
                true
            )
            local price = valid_text(service.Price or "", Config.Companies.ServicePriceMaxLength, true)
            if not valid_service_id(service.Id) or not title or not service_description or not price
                or type(service.RequestsEnabled) ~= "boolean"
            then
                error(("[sky_phone] Company '%s' has an invalid default service."):format(company_id))
            end
            service.Title = title
            service.Description = service_description
            service.Price = price
            if configured_service_ids[service.Id] then
                error(("[sky_phone] Default company service ID '%s' is configured more than once."):format(service.Id))
            end
            configured_service_ids[service.Id] = true
        end
    end

    table.sort(definition_ids, function(left, right)
        local left_name = definitions[left].Name:lower()
        local right_name = definitions[right].Name:lower()
        return left_name == right_name and left < right or left_name < right_name
    end)
end

local function seed_companies()
    if #definition_ids > 0 then
        local placeholders = {}
        local numbers = {}
        for index, company_id in ipairs(definition_ids) do
            placeholders[index] = "?"
            numbers[index] = definitions[company_id].ServiceLine.Number
        end
        local collisions = Bridge.Database.Query(([[
            SELECT `phone_number` FROM `sky_phone_sims`
            WHERE `phone_number` IN (%s)
            LIMIT 1
        ]]):format(table.concat(placeholders, ", ")), numbers)
        if collisions[1] then
            error(("[sky_phone] Company service number '%s' collides with an existing SIM."):format(
                tostring(collisions[1].phone_number)
            ))
        end
    end

    for _, company_id in ipairs(definition_ids) do
        local definition = definitions[company_id]
        local location = definition.Location
        if location then
            Bridge.Database.Query([[
                INSERT IGNORE INTO `sky_phone_company_profiles`
                    (`company_id`, `description`, `district`, `location_label`, `address`,
                        `location_x`, `location_y`, `location_z`, `availability`, `accepts_requests`)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ]], {
                company_id,
                definition.Description or "",
                definition.District or "",
                definition.LocationLabel or definition.Address or "",
                definition.Address or "",
                location.x,
                location.y,
                location.z,
                definition.DefaultAvailability or "closed",
                definition.AcceptsRequests and 1 or 0,
            })
        else
            Bridge.Database.Query([[
                INSERT IGNORE INTO `sky_phone_company_profiles`
                    (`company_id`, `description`, `district`, `location_label`, `address`,
                        `availability`, `accepts_requests`)
                VALUES (?, ?, ?, ?, ?, ?, ?)
            ]], {
                company_id,
                definition.Description or "",
                definition.District or "",
                definition.LocationLabel or definition.Address or "",
                definition.Address or "",
                definition.DefaultAvailability or "closed",
                definition.AcceptsRequests and 1 or 0,
            })
        end
        for index, service in ipairs(definition.Services or {}) do
            Bridge.Database.Query([[
                INSERT IGNORE INTO `sky_phone_company_services`
                    (`id`, `company_id`, `title`, `description`, `price_text`, `requests_enabled`, `active`, `sort_order`)
                VALUES (?, ?, ?, ?, ?, ?, 1, ?)
            ]], {
                service.Id,
                company_id,
                service.Title,
                service.Description or "",
                service.Price or "",
                service.RequestsEnabled and 1 or 0,
                index,
            })
            local seeded = Bridge.Database.Query(
                "SELECT `company_id` FROM `sky_phone_company_services` WHERE `id` = ? LIMIT 1",
                { service.Id }
            )
            if not seeded[1] or seeded[1].company_id ~= company_id then
                error(("[sky_phone] Default service ID '%s' collides with another company."):format(service.Id))
            end
        end
    end

end

local function tombstone_removed_companies()
    local profiles = Bridge.Database.Query([[
        SELECT DISTINCT profile.`company_id`
        FROM `sky_phone_company_profiles` profile
        INNER JOIN `sky_phone_company_requests` request ON request.`company_id` = profile.`company_id`
        WHERE request.`status` NOT IN ('completed', 'cancelled')
    ]], {})
    for _, profile in ipairs(profiles) do
        if not definitions[profile.company_id] then
            local mutation_token = uuid()
            if not Bridge.Database.Transaction({
                {
                    query = [[
                        UPDATE `sky_phone_company_requests`
                        SET `status` = 'cancelled', `revision` = `revision` + 1,
                            `customer_unread` = `customer_unread` + 1,
                            `cancelled_at` = CURRENT_TIMESTAMP, `mutation_token` = ?
                        WHERE `company_id` = ? AND `status` NOT IN ('completed', 'cancelled')
                    ]],
                    params = { mutation_token, profile.company_id },
                },
                {
                    query = [[
                        INSERT INTO `sky_phone_company_request_events`
                            (`id`, `request_id`, `event_type`, `actor_type`, `to_status`, `detail`)
                        SELECT UUID(), `id`, 'cancelled', 'system', 'cancelled', 'company_removed'
                        FROM `sky_phone_company_requests`
                        WHERE `company_id` = ? AND `mutation_token` = ?
                    ]],
                    params = { profile.company_id, mutation_token },
                },
            }) then
                error(("[sky_phone] Could not tombstone removed company '%s'."):format(
                    tostring(profile.company_id)
                ))
            end
        end
    end
end

local function service_line_payload(company_id)
    local definition = definitions[company_id]
    if not Config.Companies.Enabled or not definition then
        return nil
    end
    local line = definition.ServiceLine
    return {
        companyId = company_id,
        number = line.Number,
        name = definition.Name,
        canCall = line.CanCall == true,
        canMessage = line.CanMessage == true,
        autoContact = line.AutoContact == true,
        routing = line.Routing,
        icon = definition.Icon,
    }
end

function SkyPhoneCompanies.GetServiceLine(number)
    local normalized = SkyPhoneSimNumber.NormalizeService(number, Config.Sim.NumberLength)
    return normalized and service_line_payload(service_lines_by_number[normalized]) or nil
end

function SkyPhoneCompanies.GetServiceLineForCompany(company_id)
    return type(company_id) == "string" and service_line_payload(company_id) or nil
end

function SkyPhoneCompanies.IsServiceNumber(number)
    local normalized = SkyPhoneSimNumber.NormalizeService(number, Config.Sim.NumberLength)
    return normalized ~= nil and service_lines_by_number[normalized] ~= nil
end

function SkyPhoneCompanies.IsSystemContactNumber(number)
    if not Config.Companies.Enabled then
        return false
    end
    local normalized = SkyPhoneSimNumber.NormalizeService(number, Config.Sim.NumberLength)
    local company_id = normalized and service_lines_by_number[normalized] or nil
    local definition = company_id and definitions[company_id] or nil
    return definition ~= nil and definition.Public == true and definition.ServiceLine.AutoContact == true
end

function SkyPhoneCompanies.GetSystemContacts()
    local contacts = {}
    if not Config.Companies.Enabled then
        return contacts
    end
    for _, company_id in ipairs(definition_ids) do
        local definition = definitions[company_id]
        local line = definition.ServiceLine
        if definition.Public and line.AutoContact then
            contacts[#contacts + 1] = {
                id = "company:" .. company_id,
                companyId = company_id,
                name = definition.Name,
                organization = definition.Name,
                phone_number = line.Number,
                avatar_url = definition.LogoUrl,
                source = "company",
                readonly = true,
                canCall = line.CanCall == true,
                canMessage = line.CanMessage == true,
                verified = definition.Verified == true,
            }
        end
    end
    return contacts
end

function SkyPhoneCompanies.ClearCallAvailability(source)
    call_availability[tonumber(source) or source] = nil
end

local function current_device(source, registered_required)
    local session, error_response = SkyPhone.RequireSession(source)
    if not session then
        return nil, error_response
    end
    local device = SkyPhone.LoadDevice(session.imei)
    if not device then
        return nil, { success = false, error = "request_failed" }
    end
    if not device.sim_id then
        return nil, { success = false, error = "no_sim" }
    end
    if registered_required and (device.sim_type ~= "registered" or not device.registered_at) then
        return nil, { success = false, error = "anonymous_sim" }
    end
    return device
end

local function membership(source)
    local job = Bridge.Framework.GetJob(source)
    local company_id = definitions_by_job[job.name]
    if not company_id then
        return nil
    end
    return {
        company_id = company_id,
        definition = definitions[company_id],
        grade = tonumber(job.grade) or 0,
        grade_label = job.gradeLabel or job.label or "",
    }
end

local function require_permission(source, permission)
    local member = membership(source)
    if not member then
        return nil, { success = false, error = "not_authorized" }
    end
    local minimum = permission_grade(member.definition, permission)
    if not minimum or member.grade < minimum then
        return nil, { success = false, error = "not_authorized" }
    end
    local identifier = Bridge.Framework.GetIdentifier(source)
    if type(identifier) ~= "string" or identifier == "" then
        return nil, { success = false, error = "not_authorized" }
    end
    member.identifier = identifier
    return member
end

local function call_member(source)
    local member = membership(source)
    if not member then
        return nil
    end
    local minimum = tonumber(member.definition.ServiceLine.MinimumGrade) or 0
    if member.grade < minimum then
        return nil
    end
    return member
end

function SkyPhoneCompanies.CanAnswerCompanyCall(source, company_id, imei, sim_id)
    source = tonumber(source)
    if not Config.Companies.Enabled or not source or type(company_id) ~= "string"
        or type(imei) ~= "string" or type(sim_id) ~= "string"
    then
        return false
    end
    local readiness = call_availability[source]
    local member = readiness and call_member(source) or nil
    return member ~= nil
        and member.company_id == company_id
        and member.definition.ServiceLine.CanCall == true
        and readiness.company_id == company_id
        and readiness.imei == imei
        and readiness.sim_id == sim_id
end

function SkyPhoneCompanies.CanPlaceCompanyCall(source, company_id)
    source = tonumber(source)
    if not Config.Companies.Enabled or not source or type(company_id) ~= "string" then
        return false
    end
    local member = call_member(source)
    return member ~= nil and member.company_id == company_id
        and member.definition.ServiceLine.CanCall == true
end

function SkyPhoneCompanies.GetCallTargets(company_id)
    local targets = {}
    local definition = definitions[company_id]
    if not Config.Companies.Enabled or not definition or not definition.ServiceLine.CanCall then
        return targets
    end
    local online = {}
    for _, player_source in ipairs(Bridge.Framework.GetPlayers()) do
        online[tonumber(player_source) or player_source] = true
    end
    for source, readiness in pairs(call_availability) do
        local member = online[source] and call_member(source) or nil
        local device = member and SkyPhone.LoadDevice(readiness.imei) or nil
        local device_slots = device and SkyPhone.FindDeviceSlots(source, readiness.imei) or {}
        local readiness_valid = member and device and device_slots[1]
            and member.company_id == readiness.company_id
            and device.sim_id == readiness.sim_id
            and device.sim_type == "registered"
            and device.registered_at ~= nil
        if not readiness_valid then
            call_availability[source] = nil
        elseif readiness.company_id == company_id then
            targets[#targets + 1] = {
                source = source,
                simId = device.sim_id,
                phoneNumber = device.phone_number,
                imei = device.imei,
                deviceName = device.device_name,
            }
        end
    end
    table.sort(targets, function(left, right)
        return left.source < right.source
    end)
    if #targets < 2 then
        return targets
    end
    local start = (round_robin_positions[company_id] or 0) % #targets + 1
    local ordered = {}
    for offset = 0, #targets - 1 do
        ordered[#ordered + 1] = targets[(start + offset - 1) % #targets + 1]
    end
    round_robin_positions[company_id] = start
    return ordered
end

local function profile_row(company_id)
    local rows = Bridge.Database.Query([[
        SELECT p.`company_id`, p.`description`, p.`district`, p.`location_label`, p.`address`,
            p.`location_x`, p.`location_y`, p.`location_z`, p.`availability`,
            UNIX_TIMESTAMP(p.`availability_updated_at`) AS `availability_updated_at_unix`,
            UNIX_TIMESTAMP(p.`availability_expires_at`) AS `availability_expires_at_unix`,
            p.`logo_media_id`, p.`cover_media_id`, p.`accepts_requests`, p.`revision`,
            UNIX_TIMESTAMP(p.`updated_at`) AS `updated_at_unix`,
            logo.`url` AS `logo_url`, cover.`url` AS `cover_url`
        FROM `sky_phone_company_profiles` p
        LEFT JOIN `sky_phone_media` logo ON logo.`id` = p.`logo_media_id`
        LEFT JOIN `sky_phone_media` cover ON cover.`id` = p.`cover_media_id`
        WHERE p.`company_id` = ?
        LIMIT 1
    ]], { company_id })
    return rows[1]
end

local function company_services(company_id, include_inactive)
    local condition = include_inactive and " AND `archived` = 0"
        or " AND `archived` = 0 AND `active` = 1"
    local rows = Bridge.Database.Query(([[
        SELECT `id`, `title`, `description`, `price_text`, `requests_enabled`, `active`
        FROM `sky_phone_company_services`
        WHERE `company_id` = ?%s
        ORDER BY `sort_order`, `title`, `id`
    ]]):format(condition), { company_id })
    local services = {}
    for _, row in ipairs(rows) do
        services[#services + 1] = {
            id = row.id,
            title = row.title,
            description = row.description,
            priceText = row.price_text ~= "" and row.price_text or nil,
            acceptsRequests = tonumber(row.requests_enabled) == 1,
            active = tonumber(row.active) == 1,
        }
    end
    return services
end

local function company_hours(company_id)
    local rows = Bridge.Database.Query([[
        SELECT `weekday`, `is_closed`, `opens_at`, `closes_at`
        FROM `sky_phone_company_hours`
        WHERE `company_id` = ?
        ORDER BY `weekday`
    ]], { company_id })
    local hours = {}
    for _, row in ipairs(rows) do
        hours[#hours + 1] = {
            day = tonumber(row.weekday),
            isClosed = tonumber(row.is_closed) == 1,
            opensAt = row.opens_at,
            closesAt = row.closes_at,
        }
    end
    return hours
end

local function current_announcement(company_id)
    local rows = Bridge.Database.Query([[
        SELECT `body`, UNIX_TIMESTAMP(`expires_at`) AS `expires_at_unix`,
            UNIX_TIMESTAMP(`created_at`) AS `created_at_unix`
        FROM `sky_phone_company_announcements`
        WHERE `company_id` = ? AND `active` = 1
            AND (`expires_at` IS NULL OR `expires_at` > CURRENT_TIMESTAMP)
        ORDER BY `created_at` DESC
        LIMIT 1
    ]], { company_id })
    local row = rows[1]
    return row and {
        body = row.body,
        expiresAt = iso_time(row.expires_at_unix),
        publishedAt = iso_time(row.created_at_unix),
    } or nil
end

local function company_payload(company_id, include_inactive_services)
    local definition = definitions[company_id]
    local row = definition and profile_row(company_id) or nil
    if not definition or not row then
        return nil
    end
    local services = company_services(company_id, include_inactive_services)
    local availability = row.availability
    local availability_expires = tonumber(row.availability_expires_at_unix)
    if availability_expires and availability_expires <= os.time() then
        availability = definition.DefaultAvailability or "closed"
    end
    local location = nil
    local x = tonumber(row.location_x)
    local y = tonumber(row.location_y)
    local z = tonumber(row.location_z)
    if x and y and z then
        location = {
            address = row.address,
            district = row.district,
            label = row.location_label,
            coords = { x = x, y = y, z = z },
        }
    end
    local line = definition.ServiceLine
    return {
        id = company_id,
        name = definition.Name,
        categoryId = definition.Category,
        categoryName = definition.Category,
        verified = definition.Verified == true,
        description = row.description,
        availability = availability,
        availabilityUpdatedAt = iso_time(row.availability_updated_at_unix)
            or iso_time(row.updated_at_unix),
        acceptsRequests = tonumber(row.accepts_requests) == 1 and not definition.Emergency,
        phoneNumber = line and line.Number or nil,
        canCall = line and line.CanCall == true or false,
        canMessage = line and line.CanMessage == true or false,
        location = location,
        logoUrl = row.logo_url or definition.LogoUrl,
        coverUrl = row.cover_url,
        serviceSummary = services[1] and services[1].title or "",
        announcement = current_announcement(company_id),
        services = services,
        hours = company_hours(company_id),
        revision = tonumber(row.revision) or 1,
        updatedAtUnix = tonumber(row.updated_at_unix) or 0,
    }
end

local function public_company(company_id)
    local definition = definitions[company_id]
    if not definition or not definition.Public then
        return nil
    end
    return company_payload(company_id, false)
end

local function category_payloads()
    local categories = {}
    for _, category_id in ipairs(Config.Companies.Categories or {}) do
        categories[#categories + 1] = { id = category_id, name = category_id }
    end
    return categories
end

local function allow_read(source, operation)
    if not Config.Companies.Enabled then
        return nil, { success = false, error = "service_unavailable" }
    end
    local limit = Config.Companies.RateLimits[operation] or Config.Companies.RateLimits.Read
    if not SkyPhone.AllowOperation(source, "companies_" .. operation:lower(), limit, 60) then
        return nil, { success = false, error = "rate_limited" }
    end
    local session, error_response = SkyPhone.RequireSession(source)
    if not session then
        return nil, error_response
    end
    return session
end

local function cleanup_retained_data()
    local cutoff = os.time() - Config.Companies.RetentionDays * 86400
    local success = Bridge.Database.Transaction({
        {
            query = [[
                DELETE FROM `sky_phone_company_requests`
                WHERE `status` IN ('completed', 'cancelled')
                    AND COALESCE(`completed_at`, `cancelled_at`, `updated_at`) < FROM_UNIXTIME(?)
            ]],
            params = { cutoff },
        },
        {
            query = [[
                DELETE FROM `sky_phone_company_audit`
                WHERE `created_at` < FROM_UNIXTIME(?)
            ]],
            params = { cutoff },
        },
        {
            query = [[
                DELETE FROM `sky_phone_company_announcements`
                WHERE (`active` = 0 OR `expires_at` <= CURRENT_TIMESTAMP)
                    AND `created_at` < FROM_UNIXTIME(?)
            ]],
            params = { cutoff },
        },
    })
    if not success then
        Bridge.Debug("error", "[sky_phone] Companies retention cleanup failed.")
    end
end

local function refresh_runtime_configuration()
    definitions = {}
    definition_ids = {}
    definitions_by_job = {}
    service_lines_by_number = {}
    validate_configuration()
    seed_companies()
    tombstone_removed_companies()
end

refresh_runtime_configuration()

AddEventHandler("sky_phone:configurator:serverUpdated", function()
    refresh_runtime_configuration()
end)

cleanup_retained_data()

CreateThread(function()
    while true do
        Wait(24 * 60 * 60 * 1000)
        cleanup_retained_data()
    end
end)

CreateThread(function()
    while true do
        Wait(1000)
        local online = {}
        for _, player_source in ipairs(Bridge.Framework.GetPlayers()) do
            online[tonumber(player_source) or player_source] = true
        end
        for source, readiness in pairs(call_availability) do
            local member = online[source] and call_member(source) or nil
            if not member or member.company_id ~= readiness.company_id
                or member.definition.ServiceLine.CanCall ~= true
            then
                call_availability[source] = nil
            end
        end
    end
end)

local function company_summary(company)
    return {
        id = company.id,
        name = company.name,
        categoryId = company.categoryId,
        categoryName = company.categoryName,
        verified = company.verified,
        description = company.description,
        availability = company.availability,
        availabilityUpdatedAt = company.availabilityUpdatedAt,
        acceptsRequests = company.acceptsRequests,
        phoneNumber = company.phoneNumber,
        canCall = company.canCall,
        canMessage = company.canMessage,
        location = company.location,
        logoUrl = company.logoUrl,
        serviceSummary = company.serviceSummary,
        announcement = company.announcement,
    }
end

local function search_score(company, search)
    if search == "" then
        return 0
    end
    local name = company.name:lower()
    if name:sub(1, #search) == search then
        return 4
    end
    if name:find(search, 1, true) then
        return 3
    end
    local values = {
        company.categoryId,
        company.description,
        company.location and company.location.district or "",
        company.location and company.location.address or "",
        company.serviceSummary,
    }
    for _, value in ipairs(values) do
        if tostring(value):lower():find(search, 1, true) then
            return 1
        end
    end
    for _, service in ipairs(company.services) do
        if service.title:lower():find(search, 1, true)
            or service.description:lower():find(search, 1, true)
        then
            return 1
        end
    end
    return -1
end

Bridge.Callbacks.Register("sky_phone:companies:list", function(source, data)
    local session, error_response = allow_read(source, "Search")
    if not session then
        return error_response
    end
    data = type(data) == "table" and data or {}
    local search = valid_text(data.search or "", 80, true)
    if not search then
        return { success = false, error = "invalid_request" }
    end
    search = search:lower()
    local category_id = data.categoryId
    if category_id ~= nil then
        local category_valid = false
        for _, configured in ipairs(Config.Companies.Categories or {}) do
            if category_id == configured then
                category_valid = true
                break
            end
        end
        if not category_valid then
            return { success = false, error = "invalid_request" }
        end
    end
    local availability = data.availability
    if availability ~= nil and not Config.Companies.AvailabilityStatuses[availability] then
        return { success = false, error = "invalid_request" }
    end
    if data.acceptsRequests ~= nil and type(data.acceptsRequests) ~= "boolean" then
        return { success = false, error = "invalid_request" }
    end
    if data.hasLocation ~= nil and type(data.hasLocation) ~= "boolean" then
        return { success = false, error = "invalid_request" }
    end
    local sort = data.sort or "relevance"
    if sort ~= "relevance" and sort ~= "name" and sort ~= "updated" then
        return { success = false, error = "invalid_request" }
    end
    local cursor = data.cursor == nil and 0 or valid_integer(data.cursor, 0, 100000)
    if not cursor then
        return { success = false, error = "invalid_request" }
    end

    local matches = {}
    for _, company_id in ipairs(definition_ids) do
        local company = public_company(company_id)
        if company then
            local score = search_score(company, search)
            if score >= 0
                and (not category_id or company.categoryId == category_id)
                and (not availability or company.availability == availability)
                and (data.acceptsRequests ~= true or company.acceptsRequests)
                and (data.hasLocation ~= true or company.location ~= nil)
            then
                matches[#matches + 1] = { company = company, score = score }
            end
        end
    end
    table.sort(matches, function(left, right)
        if sort == "updated" and left.company.updatedAtUnix ~= right.company.updatedAtUnix then
            return left.company.updatedAtUnix > right.company.updatedAtUnix
        end
        if sort == "relevance" and left.score ~= right.score then
            return left.score > right.score
        end
        local left_name = left.company.name:lower()
        local right_name = right.company.name:lower()
        return left_name == right_name and left.company.id < right.company.id or left_name < right_name
    end)

    local companies = {}
    local page_size = math.min(Config.Companies.PageSize, Config.Companies.MaximumPageSize)
    local last_index = math.min(#matches, cursor + page_size)
    for index = cursor + 1, last_index do
        companies[#companies + 1] = company_summary(matches[index].company)
    end
    return {
        success = true,
        data = {
            companies = companies,
            categories = category_payloads(),
            nextCursor = last_index < #matches and tostring(last_index) or nil,
        },
    }
end)

Bridge.Callbacks.Register("sky_phone:companies:get", function(source, data)
    local session, error_response = allow_read(source, "Read")
    if not session then
        return error_response
    end
    local company_id = type(data) == "table" and data.companyId or nil
    local company = type(company_id) == "string" and public_company(company_id) or nil
    if not company then
        return { success = false, error = "company_not_found" }
    end
    company.updatedAtUnix = nil
    return { success = true, data = { company = company } }
end)

local function decode_request_cursor(value)
    if value == nil then
        return nil, nil
    end
    if type(value) ~= "string" or #value > 64 then
        return false, false
    end
    local timestamp, request_id = value:match("^(%d+):(.+)$")
    timestamp = valid_integer(timestamp, 1, 4102444800)
    if not timestamp or not valid_uuid(request_id) then
        return false, false
    end
    return timestamp, request_id
end

local function encode_request_cursor(row)
    return ("%s:%s"):format(tostring(math.floor(tonumber(row.updated_at_unix) or 0)), row.id)
end

local function request_row(request_id)
    local rows = Bridge.Database.Query([[
        SELECT r.`id`, r.`company_id`, r.`service_id`, r.`customer_sim_id`, r.`subject`, r.`description`,
            r.`status`, r.`assigned_identifier`, r.`customer_unread`,
            r.`company_activity_revision`, r.`revision`,
            UNIX_TIMESTAMP(r.`created_at`) AS `created_at_unix`,
            UNIX_TIMESTAMP(r.`updated_at`) AS `updated_at_unix`, service.`title` AS `service_title`,
            logo.`url` AS `company_logo_url`
        FROM `sky_phone_company_requests` r
        LEFT JOIN `sky_phone_company_services` service ON service.`id` = r.`service_id`
        LEFT JOIN `sky_phone_company_profiles` profile ON profile.`company_id` = r.`company_id`
        LEFT JOIN `sky_phone_media` logo ON logo.`id` = profile.`logo_media_id`
        WHERE r.`id` = ?
        LIMIT 1
    ]], { request_id })
    return rows[1]
end

local function request_summary(row, audience, identifier)
    local definition = definitions[row.company_id]
    local assigned_label = nil
    if row.assigned_identifier then
        assigned_label = identifier and row.assigned_identifier == identifier and "you" or "assigned"
    end
    local unread_count
    if audience == "customer" then
        unread_count = tonumber(row.customer_unread) or 0
    else
        local relevant = not terminal_statuses[row.status]
            and (row.status == "new" or row.assigned_identifier == identifier)
        unread_count = relevant and math.max(
            0,
            (tonumber(row.company_activity_revision) or 1)
                - (tonumber(row.company_read_revision) or 0)
        ) or 0
    end
    return {
        id = row.id,
        companyId = row.company_id,
        companyName = definition and definition.Name or row.company_id,
        companyLogoUrl = row.company_logo_url,
        serviceId = row.service_id,
        serviceName = row.service_title,
        subject = row.subject,
        status = row.status,
        assignedLabel = assigned_label,
        unreadCount = unread_count,
        createdAt = iso_time(row.created_at_unix),
        updatedAt = iso_time(row.updated_at_unix),
    }
end

local function request_access(source, request_id)
    local session, error_response = SkyPhone.RequireSession(source)
    if not session then
        return nil, error_response
    end
    local row = request_row(request_id)
    if not row then
        return nil, { success = false, error = "request_not_found" }
    end
    local device = SkyPhone.LoadDevice(session.imei)
    if not device then
        return nil, { success = false, error = "request_failed" }
    end
    if device.sim_id and device.sim_id == row.customer_sim_id
        and device.sim_type == "registered" and device.registered_at
    then
        return { audience = "customer", row = row, device = device }
    end
    local member = membership(source)
    if not member or member.company_id ~= row.company_id
        or member.grade < permission_grade(member.definition, "WorkQueue")
    then
        return nil, { success = false, error = "request_not_found" }
    end
    local identifier = Bridge.Framework.GetIdentifier(source)
    if type(identifier) ~= "string" or identifier == "" then
        return nil, { success = false, error = "not_authorized" }
    end
    member.identifier = identifier
    return { audience = "company", row = row, device = device, member = member }
end

local function can_handle_request(access)
    if access.audience ~= "company" then
        return false
    end
    return access.row.assigned_identifier == access.member.identifier
        or access.member.grade >= permission_grade(access.member.definition, "Assign")
end

local function request_actions(access)
    local row = access.row
    local definition = definitions[row.company_id]
    local active = not terminal_statuses[row.status]
    if access.audience == "customer" then
        return {
            allowedStatuses = {},
            canAssign = false,
            canCall = definition ~= nil and definition.ServiceLine.CanCall == true,
            canCancel = active,
            canClaim = false,
            canReply = active,
        }
    end
    local handler = can_handle_request(access)
    local allowed = {}
    if handler then
        for _, status in ipairs({ "in_progress", "waiting_customer", "completed", "cancelled" }) do
            if status_transitions[row.status] and status_transitions[row.status][status] then
                allowed[#allowed + 1] = status
            end
        end
    end
    return {
        allowedStatuses = allowed,
        canAssign = active and access.member.grade >= permission_grade(access.member.definition, "Assign"),
        canCall = active
            and access.member.definition.ServiceLine.CanCall == true
            and access.member.grade >= (tonumber(access.member.definition.ServiceLine.MinimumGrade) or 0),
        canCancel = active and handler,
        canClaim = row.status == "new" and not row.assigned_identifier,
        canReply = active and handler,
    }
end

local function request_detail(access)
    local row = request_row(access.row.id)
    if not row then
        return nil
    end
    access.row = row
    if access.audience == "customer" then
        Bridge.Database.Query(
            "UPDATE `sky_phone_company_requests` SET `customer_unread` = 0, `updated_at` = `updated_at` WHERE `id` = ?",
            { row.id }
        )
        row.customer_unread = 0
    else
        Bridge.Database.Query([[
            INSERT INTO `sky_phone_company_request_reads`
                (`request_id`, `reader_identifier`, `read_revision`)
            VALUES (?, ?, ?)
            ON DUPLICATE KEY UPDATE
                `read_revision` = GREATEST(`read_revision`, VALUES(`read_revision`)),
                `updated_at` = CURRENT_TIMESTAMP
        ]], { row.id, access.member.identifier, row.company_activity_revision })
        row.company_read_revision = row.company_activity_revision
    end
    local messages = Bridge.Database.Query([[
        SELECT `id`, `sender_type`, `sender_identifier`, `sender_sim_id`, `body`,
            UNIX_TIMESTAMP(`created_at`) AS `created_at_unix`
        FROM `sky_phone_company_request_messages`
        WHERE `request_id` = ?
        ORDER BY `created_at`, `id`
    ]], { row.id })
    local message_payloads = {}
    for _, message in ipairs(messages) do
        local mine = access.audience == "customer"
            and message.sender_type == "customer" and message.sender_sim_id == row.customer_sim_id
            or access.audience == "company"
                and message.sender_type == "company" and message.sender_identifier == access.member.identifier
        message_payloads[#message_payloads + 1] = {
            id = message.id,
            author = message.sender_type,
            authorLabel = mine and "you" or message.sender_type,
            body = message.body,
            createdAt = iso_time(message.created_at_unix),
            isMine = mine,
        }
    end
    local events = Bridge.Database.Query([[
        SELECT `id`, `event_type`, `to_status`, UNIX_TIMESTAMP(`created_at`) AS `created_at_unix`
        FROM `sky_phone_company_request_events`
        WHERE `request_id` = ?
        ORDER BY `created_at`, `id`
    ]], { row.id })
    local event_payloads = {}
    for _, event in ipairs(events) do
        local event_type = event.event_type
        if event_type == "status" then
            event_type = event.to_status == "completed" and "completed" or "status_changed"
        end
        event_payloads[#event_payloads + 1] = {
            id = event.id,
            type = event_type,
            status = event.to_status,
            createdAt = iso_time(event.created_at_unix),
        }
    end
    local media_rows = Bridge.Database.Query([[
        SELECT media.`id`, media.`url`
        FROM `sky_phone_company_request_media` request_media
        INNER JOIN `sky_phone_media` media ON media.`id` = request_media.`media_id`
        WHERE request_media.`request_id` = ?
        ORDER BY request_media.`sort_order`
    ]], { row.id })
    local payload = request_summary(
        row,
        access.audience,
        access.member and access.member.identifier or nil
    )
    payload.description = row.description
    payload.revision = tonumber(row.revision) or 1
    local definition = definitions[row.company_id]
    payload.phoneNumber = definition and definition.ServiceLine.Number or nil
    payload.messages = message_payloads
    payload.events = event_payloads
    payload.media = media_rows
    payload.actions = request_actions(access)
    return payload
end

local function list_request_rows(query, parameters, audience, identifier)
    local rows = Bridge.Database.Query(query, parameters)
    local has_more = #rows > Config.Companies.PageSize
    if has_more then
        rows[#rows] = nil
    end
    local requests = {}
    for _, row in ipairs(rows) do
        requests[#requests + 1] = request_summary(row, audience, identifier)
    end
    return requests, has_more and encode_request_cursor(rows[#rows]) or nil
end

local request_list_select = [[
    SELECT r.`id`, r.`company_id`, r.`service_id`, r.`customer_sim_id`, r.`subject`, r.`status`,
        r.`assigned_identifier`, r.`customer_unread`, r.`company_activity_revision`, r.`revision`,
        UNIX_TIMESTAMP(r.`created_at`) AS `created_at_unix`,
        UNIX_TIMESTAMP(r.`updated_at`) AS `updated_at_unix`, service.`title` AS `service_title`,
        logo.`url` AS `company_logo_url`, NULL AS `company_read_revision`
    FROM `sky_phone_company_requests` r
    LEFT JOIN `sky_phone_company_services` service ON service.`id` = r.`service_id`
    LEFT JOIN `sky_phone_company_profiles` profile ON profile.`company_id` = r.`company_id`
    LEFT JOIN `sky_phone_media` logo ON logo.`id` = profile.`logo_media_id`
]]

local company_request_list_select = [[
    SELECT r.`id`, r.`company_id`, r.`service_id`, r.`customer_sim_id`, r.`subject`, r.`status`,
        r.`assigned_identifier`, r.`customer_unread`, r.`company_activity_revision`, r.`revision`,
        UNIX_TIMESTAMP(r.`created_at`) AS `created_at_unix`,
        UNIX_TIMESTAMP(r.`updated_at`) AS `updated_at_unix`, service.`title` AS `service_title`,
        logo.`url` AS `company_logo_url`, company_read.`read_revision` AS `company_read_revision`
    FROM `sky_phone_company_requests` r
    LEFT JOIN `sky_phone_company_services` service ON service.`id` = r.`service_id`
    LEFT JOIN `sky_phone_company_profiles` profile ON profile.`company_id` = r.`company_id`
    LEFT JOIN `sky_phone_media` logo ON logo.`id` = profile.`logo_media_id`
    LEFT JOIN `sky_phone_company_request_reads` company_read
        ON company_read.`request_id` = r.`id` AND company_read.`reader_identifier` = ?
]]

local function context_request_rows(company_id, identifier, own)
    local condition = own
        and " AND r.`assigned_identifier` = ? AND r.`status` NOT IN ('completed', 'cancelled')"
        or ""
    local parameters = { identifier, company_id }
    if own then
        parameters[#parameters + 1] = identifier
    end
    parameters[#parameters + 1] = 4
    local rows = Bridge.Database.Query(company_request_list_select .. ([=[
        WHERE r.`company_id` = ?%s
        ORDER BY r.`updated_at` DESC, r.`id` DESC
        LIMIT ?
    ]=]):format(condition), parameters)
    local requests = {}
    for _, row in ipairs(rows) do
        requests[#requests + 1] = request_summary(row, "company", identifier)
    end
    return requests
end

local function work_context(source)
    local member = membership(source)
    if not member or member.grade < permission_grade(member.definition, "WorkQueue") then
        return {
            authorized = false,
            callAvailable = false,
            company = nil,
            metrics = { assigned = 0, completedToday = 0, new = 0, waiting = 0 },
            ownRequests = {},
            recentRequests = {},
            permissions = {
                canAssign = false,
                canManageAnnouncement = false,
                canManageHours = false,
                canManageProfile = false,
                canManageServices = false,
                canSetAvailability = false,
                canTakeCalls = false,
            },
            role = nil,
            unreadCount = 0,
        }
    end
    local identifier = Bridge.Framework.GetIdentifier(source)
    if type(identifier) ~= "string" or identifier == "" then
        return nil
    end
    member.identifier = identifier
    local rows = Bridge.Database.Query([[
        SELECT
            COALESCE(SUM(request.`status` = 'new'), 0) AS `new_count`,
            COALESCE(SUM(request.`assigned_identifier` = ?
                AND request.`status` NOT IN ('completed', 'cancelled')), 0) AS `assigned_count`,
            COALESCE(SUM(request.`status` = 'waiting_customer'), 0) AS `waiting_count`,
            COALESCE(SUM(request.`status` = 'completed'
                AND DATE(request.`completed_at`) = CURRENT_DATE), 0) AS `completed_today`,
            COALESCE(SUM(CASE
                WHEN request.`status` NOT IN ('completed', 'cancelled')
                    AND (request.`status` = 'new' OR request.`assigned_identifier` = ?)
                    AND COALESCE(company_read.`read_revision`, 0) < request.`company_activity_revision`
                    THEN request.`company_activity_revision` - COALESCE(company_read.`read_revision`, 0)
                ELSE 0
            END), 0) AS `unread_count`
        FROM `sky_phone_company_requests` request
        LEFT JOIN `sky_phone_company_request_reads` company_read
            ON company_read.`request_id` = request.`id` AND company_read.`reader_identifier` = ?
        WHERE request.`company_id` = ?
    ]], { identifier, identifier, identifier, member.company_id })
    local metrics = rows[1] or {}
    local permissions = {
        canAssign = member.grade >= permission_grade(member.definition, "Assign"),
        canManageAnnouncement = member.grade >= permission_grade(member.definition, "Announcement"),
        canManageHours = member.grade >= permission_grade(member.definition, "Hours"),
        canManageProfile = member.grade >= permission_grade(member.definition, "Profile"),
        canManageServices = member.grade >= permission_grade(member.definition, "Services"),
        canSetAvailability = member.grade >= permission_grade(member.definition, "Availability"),
        canTakeCalls = member.definition.ServiceLine.CanCall == true
            and member.grade >= (tonumber(member.definition.ServiceLine.MinimumGrade) or 0),
    }
    local manager = permissions.canAssign or permissions.canManageAnnouncement
        or permissions.canManageHours or permissions.canManageProfile or permissions.canManageServices
    local readiness = call_availability[source]
    local company = company_payload(member.company_id, true)
    company.updatedAtUnix = nil
    return {
        authorized = true,
        callAvailable = permissions.canTakeCalls and readiness ~= nil
            and readiness.company_id == member.company_id,
        company = company,
        metrics = {
            new = tonumber(metrics.new_count) or 0,
            assigned = tonumber(metrics.assigned_count) or 0,
            waiting = tonumber(metrics.waiting_count) or 0,
            completedToday = tonumber(metrics.completed_today) or 0,
        },
        ownRequests = context_request_rows(member.company_id, identifier, true),
        recentRequests = context_request_rows(member.company_id, identifier, false),
        permissions = permissions,
        role = manager and "manager" or "employee",
        unreadCount = tonumber(metrics.unread_count) or 0,
    }
end

local function notify_sim(sim_id, event_name, payload)
    local devices = Bridge.Database.Query([[
        SELECT d.`imei`, d.`device_name`, settings.`payload` AS `settings`
        FROM `sky_phone_devices` d
        LEFT JOIN `sky_phone_device_data` settings
            ON settings.`device_imei` = d.`imei` AND settings.`namespace` = 'settings'
        WHERE d.`sim_id` = ?
    ]], { sim_id })
    for _, device in ipairs(devices) do
        for _, player_source in ipairs(Bridge.Framework.GetPlayers()) do
            local target = tonumber(player_source) or player_source
            if SkyPhone.FindDeviceSlots(target, device.imei)[1] then
                local event_payload = {}
                for key, value in pairs(payload) do
                    event_payload[key] = value
                end
                event_payload.device = {
                    imei = device.imei,
                    name = device.device_name,
                    settings = device.settings,
                }
                TriggerClientEvent(event_name, target, event_payload)
            end
        end
    end
end

local function notify_source(source, event_name, payload)
    local session = SkyPhone.RequireSession(source)
    if not session then
        return
    end
    local rows = Bridge.Database.Query([[
        SELECT d.`device_name`, settings.`payload` AS `settings`
        FROM `sky_phone_devices` d
        LEFT JOIN `sky_phone_device_data` settings
            ON settings.`device_imei` = d.`imei` AND settings.`namespace` = 'settings'
        WHERE d.`imei` = ?
        LIMIT 1
    ]], { session.imei })
    if not rows[1] then
        return
    end
    local event_payload = {}
    for key, value in pairs(payload) do
        event_payload[key] = value
    end
    event_payload.device = {
        imei = session.imei,
        name = rows[1].device_name,
        settings = rows[1].settings,
    }
    TriggerClientEvent(event_name, source, event_payload)
end

local function notify_company(company_id, event_name, payload, excluded_source)
    local definition = definitions[company_id]
    if not definition then
        return
    end
    for _, player_source in ipairs(Bridge.Framework.GetPlayers()) do
        local target = tonumber(player_source) or player_source
        if target ~= excluded_source then
            local job = Bridge.Framework.GetJob(target)
            if job.name == definition.Job and (tonumber(job.grade) or 0) >= permission_grade(definition, "WorkQueue") then
                notify_source(target, event_name, payload)
            end
        end
    end
end

local function notify_identifier(identifier, company_id, event_name, payload)
    for _, player_source in ipairs(Bridge.Framework.GetPlayers()) do
        local target = tonumber(player_source) or player_source
        local member = membership(target)
        if member and member.company_id == company_id
            and member.grade >= permission_grade(member.definition, "WorkQueue")
            and Bridge.Framework.GetIdentifier(target) == identifier
        then
            notify_source(target, event_name, payload)
        end
    end
end

local function emit_public_change(company_id)
    local definition = definitions[company_id]
    if not definition then
        return
    end
    notify_company(company_id, "sky_phone:companies:changed", {
        area = "work",
        companyId = company_id,
    })
    if not definition.Public then
        return
    end
    for _, player_source in ipairs(Bridge.Framework.GetPlayers()) do
        notify_source(tonumber(player_source) or player_source, "sky_phone:companies:changed", {
            area = "directory",
            companyId = company_id,
        })
    end
end

local function emit_request_change(row, customer, company, excluded_source)
    local payload = {
        area = customer and "customer" or "work",
        companyId = row.company_id,
        requestId = row.id,
    }
    if customer then
        notify_sim(row.customer_sim_id, "sky_phone:companies:changed", payload)
    end
    if company then
        payload = {
            area = "work",
            companyId = row.company_id,
            requestId = row.id,
        }
        notify_company(row.company_id, "sky_phone:companies:changed", payload, excluded_source)
    end
end

Bridge.Callbacks.Register("sky_phone:companies:my-requests", function(source, data)
    local session, error_response = allow_read(source, "Read")
    if not session then
        return error_response
    end
    local device, device_error = current_device(source, true)
    if not device then
        return device_error
    end
    data = type(data) == "table" and data or {}
    local list = data.list or "open"
    if list ~= "open" and list ~= "closed" then
        return { success = false, error = "invalid_request" }
    end
    local cursor_time, cursor_id = decode_request_cursor(data.cursor)
    if cursor_time == false then
        return { success = false, error = "invalid_request" }
    end
    local status_condition = list == "open"
        and "r.`status` NOT IN ('completed', 'cancelled')"
        or "r.`status` IN ('completed', 'cancelled')"
    local cursor_condition = ""
    local parameters = { device.sim_id }
    if cursor_time then
        cursor_condition = [[
            AND (r.`updated_at` < FROM_UNIXTIME(?)
                OR (r.`updated_at` = FROM_UNIXTIME(?) AND r.`id` < ?))
        ]]
        parameters[#parameters + 1] = cursor_time
        parameters[#parameters + 1] = cursor_time
        parameters[#parameters + 1] = cursor_id
    end
    parameters[#parameters + 1] = Config.Companies.PageSize + 1
    local requests, next_cursor = list_request_rows(request_list_select .. ([=[
        WHERE r.`customer_sim_id` = ? AND %s %s
        ORDER BY r.`updated_at` DESC, r.`id` DESC
        LIMIT ?
    ]=]):format(status_condition, cursor_condition), parameters, "customer")
    local unread_rows = Bridge.Database.Query([[
        SELECT COALESCE(SUM(`customer_unread`), 0) AS `unread_count`
        FROM `sky_phone_company_requests`
        WHERE `customer_sim_id` = ?
    ]], { device.sim_id })
    return {
        success = true,
        data = {
            requests = requests,
            nextCursor = next_cursor,
            unreadCount = tonumber(unread_rows[1] and unread_rows[1].unread_count) or 0,
        },
    }
end)

Bridge.Callbacks.Register("sky_phone:companies:get-request", function(source, data)
    local session, error_response = allow_read(source, "Read")
    if not session then
        return error_response
    end
    local request_id = type(data) == "table" and data.requestId or nil
    if not valid_uuid(request_id) then
        return { success = false, error = "invalid_request" }
    end
    local access, access_error = request_access(source, request_id)
    if not access then
        return access_error
    end
    local request = request_detail(access)
    if not request then
        return { success = false, error = "request_not_found" }
    end
    return { success = true, data = { request = request } }
end)

Bridge.Callbacks.Register("sky_phone:companies:work-context", function(source)
    local session, error_response = allow_read(source, "Read")
    if not session then
        return error_response
    end
    local context = work_context(source)
    if not context then
        return { success = false, error = "not_authorized" }
    end
    return { success = true, data = { context = context } }
end)

Bridge.Callbacks.Register("sky_phone:companies:work-queue", function(source, data)
    local session, error_response = allow_read(source, "Read")
    if not session then
        return error_response
    end
    local member, member_error = require_permission(source, "WorkQueue")
    if not member then
        return member_error
    end
    data = type(data) == "table" and data or {}
    local filter = data.filter or "new"
    local filters = {
        new = "r.`status` = 'new'",
        assigned = "r.`assigned_identifier` = ? AND r.`status` NOT IN ('completed', 'cancelled')",
        in_progress = "r.`status` = 'in_progress'",
        waiting_customer = "r.`status` = 'waiting_customer'",
        completed = "r.`status` = 'completed'",
    }
    if not filters[filter] then
        return { success = false, error = "invalid_request" }
    end
    local cursor_time, cursor_id = decode_request_cursor(data.cursor)
    if cursor_time == false then
        return { success = false, error = "invalid_request" }
    end
    local parameters = { member.identifier, member.company_id }
    if filter == "assigned" then
        parameters[#parameters + 1] = member.identifier
    end
    local cursor_condition = ""
    if cursor_time then
        cursor_condition = [[
            AND (r.`updated_at` < FROM_UNIXTIME(?)
                OR (r.`updated_at` = FROM_UNIXTIME(?) AND r.`id` < ?))
        ]]
        parameters[#parameters + 1] = cursor_time
        parameters[#parameters + 1] = cursor_time
        parameters[#parameters + 1] = cursor_id
    end
    parameters[#parameters + 1] = Config.Companies.PageSize + 1
    local requests, next_cursor = list_request_rows(company_request_list_select .. ([=[
        WHERE r.`company_id` = ? AND %s %s
        ORDER BY r.`updated_at` DESC, r.`id` DESC
        LIMIT ?
    ]=]):format(filters[filter], cursor_condition), parameters, "company", member.identifier)
    return { success = true, data = { requests = requests, nextCursor = next_cursor } }
end)

local function member_token(target, company_id, identifier)
    local entry = member_tokens[target]
    if not entry or entry.company_id ~= company_id or entry.identifier ~= identifier
        or os.time() - entry.created_at > 300
    then
        entry = {
            token = uuid(),
            company_id = company_id,
            identifier = identifier,
            created_at = os.time(),
        }
        member_tokens[target] = entry
    end
    return entry.token
end

Bridge.Callbacks.Register("sky_phone:companies:list-members", function(source)
    local session, error_response = allow_read(source, "Read")
    if not session then
        return error_response
    end
    local member, member_error = require_permission(source, "Assign")
    if not member then
        return member_error
    end
    local members = {}
    for _, player_source in ipairs(Bridge.Framework.GetPlayers()) do
        local target = tonumber(player_source) or player_source
        local target_member = membership(target)
        local target_identifier = target_member and Bridge.Framework.GetIdentifier(target) or nil
        if target_member and target_member.company_id == member.company_id
            and target_member.grade >= permission_grade(target_member.definition, "WorkQueue")
            and type(target_identifier) == "string" and target_identifier ~= ""
        then
            local first_name = trim(Bridge.Framework.GetFirstname(target) or "") or ""
            local last_name = trim(Bridge.Framework.GetLastname(target) or "") or ""
            local name = trim(first_name .. " " .. last_name)
            members[#members + 1] = {
                id = member_token(target, member.company_id, target_identifier),
                name = name,
                online = true,
                role = target_member.grade_label,
            }
        end
    end
    table.sort(members, function(left, right)
        return left.name:lower() < right.name:lower()
    end)
    return { success = true, data = { members = members } }
end)

local function allow_mutation(source, operation, limit_name)
    if not Config.Companies.Enabled then
        return false, { success = false, error = "service_unavailable" }
    end
    local limit = Config.Companies.RateLimits[limit_name]
    if not SkyPhone.AllowOperation(source, "companies_" .. operation, limit, 60) then
        return false, { success = false, error = "rate_limited" }
    end
    local session, error_response = SkyPhone.RequireSession(source)
    if not session then
        return false, error_response
    end
    return true
end

local function mutation_request_payload(source, request_id)
    local access, access_error = request_access(source, request_id)
    if not access then
        return nil, access_error
    end
    local request = request_detail(access)
    if not request then
        return nil, { success = false, error = "request_not_found" }
    end
    local data = { request = request }
    if access.audience == "company" then
        data.context = work_context(source)
    end
    return data
end

local function notification_payload(kind, area, row)
    return {
        kind = kind,
        area = area,
        companyId = row.company_id,
        requestId = row.id,
    }
end

Bridge.Callbacks.Register("sky_phone:companies:create-request", function(source, data)
    local allowed, rate_error = allow_mutation(source, "create_request", "CreateRequest")
    if not allowed then
        return rate_error
    end
    local device, device_error = current_device(source, true)
    if not device then
        return device_error
    end
    if type(data) ~= "table" then
        return { success = false, error = "invalid_request" }
    end
    local company_id = data.companyId
    local definition = type(company_id) == "string" and definitions[company_id] or nil
    if not definition or not definition.Public or definition.Emergency then
        return { success = false, error = "company_not_found" }
    end
    local subject = valid_text(data.subject, Config.Companies.SubjectMaxLength, false)
    local description = valid_text(data.description, Config.Companies.RequestBodyMaxLength, false)
    if not subject or not description or not valid_service_id(data.serviceId) then
        return { success = false, error = "invalid_request" }
    end
    local profiles = Bridge.Database.Query(
        "SELECT `accepts_requests` FROM `sky_phone_company_profiles` WHERE `company_id` = ? LIMIT 1",
        { company_id }
    )
    if not profiles[1] or tonumber(profiles[1].accepts_requests) ~= 1 then
        return { success = false, error = "invalid_service" }
    end
    local services = Bridge.Database.Query([[
        SELECT `id` FROM `sky_phone_company_services`
        WHERE `id` = ? AND `company_id` = ? AND `archived` = 0
            AND `active` = 1 AND `requests_enabled` = 1
        LIMIT 1
    ]], { data.serviceId, company_id })
    if not services[1] then
        return { success = false, error = "invalid_service" }
    end
    local media_ids = data.mediaIds
    if media_ids == nil then
        media_ids = {}
    end
    if not valid_array(media_ids, Config.Companies.MaximumRequestMedia) then
        return { success = false, error = "invalid_media" }
    end
    local media_seen = {}
    local normalized_media = {}
    for _, media_id in ipairs(media_ids) do
        local normalized = valid_integer(media_id, 1, 9007199254740991)
        if not normalized or media_seen[normalized]
            or not SkyPhoneMedia.ResolveOwnedMedia(source, normalized, "photo")
        then
            return { success = false, error = "invalid_media" }
        end
        media_seen[normalized] = true
        normalized_media[#normalized_media + 1] = normalized
    end
    local counts = Bridge.Database.Query([[
        SELECT COUNT(*) AS `count`
        FROM `sky_phone_company_requests`
        WHERE `customer_sim_id` = ? AND `status` NOT IN ('completed', 'cancelled')
    ]], { device.sim_id })
    if (tonumber(counts[1] and counts[1].count) or 0) >= Config.Companies.MaximumOpenRequestsPerSim then
        return { success = false, error = "too_many_open_requests" }
    end
    local request_id = uuid()
    local event_id = uuid()
    local statements = {
        {
            query = "UPDATE `sky_phone_sims` SET `updated_at` = `updated_at` WHERE `id` = ?",
            params = { device.sim_id },
        },
        {
            query = [[
                INSERT INTO `sky_phone_company_requests`
                    (`id`, `company_id`, `service_id`, `customer_sim_id`, `subject`, `description`)
                SELECT ?, profile.`company_id`, service.`id`, sim.`id`, ?, ?
                FROM `sky_phone_sims` sim
                INNER JOIN `sky_phone_company_profiles` profile ON profile.`company_id` = ?
                INNER JOIN `sky_phone_company_services` service
                    ON service.`id` = ? AND service.`company_id` = profile.`company_id`
                WHERE sim.`id` = ? AND profile.`accepts_requests` = 1
                    AND service.`archived` = 0 AND service.`active` = 1
                    AND service.`requests_enabled` = 1 AND (
                    SELECT COUNT(*) FROM `sky_phone_company_requests`
                    WHERE `customer_sim_id` = ? AND `status` NOT IN ('completed', 'cancelled')
                ) < ?
            ]],
            params = {
                request_id,
                subject,
                description,
                company_id,
                data.serviceId,
                device.sim_id,
                device.sim_id,
                Config.Companies.MaximumOpenRequestsPerSim,
            },
        },
        {
            query = [[
                INSERT INTO `sky_phone_company_request_events`
                    (`id`, `request_id`, `event_type`, `actor_type`, `to_status`)
                SELECT ?, `id`, 'created', 'customer', 'new'
                FROM `sky_phone_company_requests` WHERE `id` = ?
            ]],
            params = { event_id, request_id },
        },
    }
    for index, media_id in ipairs(normalized_media) do
        statements[#statements + 1] = {
            query = [[
                INSERT INTO `sky_phone_company_request_media` (`request_id`, `media_id`, `sort_order`)
                SELECT `id`, ?, ? FROM `sky_phone_company_requests` WHERE `id` = ?
            ]],
            params = { media_id, index, request_id },
        }
    end
    if not Bridge.Database.Transaction(statements) then
        return { success = false, error = "request_failed" }
    end
    local row = request_row(request_id)
    if not row then
        local available = Bridge.Database.Query([[
            SELECT service.`id`
            FROM `sky_phone_company_profiles` profile
            INNER JOIN `sky_phone_company_services` service ON service.`company_id` = profile.`company_id`
            WHERE profile.`company_id` = ? AND profile.`accepts_requests` = 1
                AND service.`id` = ? AND service.`archived` = 0
                AND service.`active` = 1 AND service.`requests_enabled` = 1
            LIMIT 1
        ]], { company_id, data.serviceId })
        if not available[1] then
            return { success = false, error = "invalid_service" }
        end
        return { success = false, error = "too_many_open_requests" }
    end
    emit_request_change(row, true, true, source)
    notify_company(company_id, "sky_phone:companies:notification", notification_payload(
        "newRequest",
        "work",
        row
    ), source)
    local payload, payload_error = mutation_request_payload(source, request_id)
    if not payload then
        return payload_error
    end
    return { success = true, data = payload }
end)

Bridge.Callbacks.Register("sky_phone:companies:cancel-request", function(source, data)
    local allowed, rate_error = allow_mutation(source, "cancel_request", "RequestAction")
    if not allowed then
        return rate_error
    end
    local request_id = type(data) == "table" and data.requestId or nil
    local revision = type(data) == "table" and valid_integer(data.revision, 1, 4294967295) or nil
    if not valid_uuid(request_id) or not revision then
        return { success = false, error = "invalid_request" }
    end
    local access, access_error = request_access(source, request_id)
    if not access then
        return access_error
    end
    if terminal_statuses[access.row.status]
        or (access.audience == "company" and not can_handle_request(access))
    then
        return { success = false, error = "invalid_status" }
    end
    local actor_type = access.audience
    local customer_unread_update = actor_type == "company"
        and ", `customer_unread` = `customer_unread` + 1" or ""
    local mutation_token = uuid()
    local event_id = uuid()
    local event_query
    local event_params
    if actor_type == "customer" then
        event_query = [[
            INSERT INTO `sky_phone_company_request_events`
                (`id`, `request_id`, `event_type`, `actor_type`, `from_status`, `to_status`)
            SELECT ?, `id`, 'cancelled', 'customer', ?, 'cancelled'
            FROM `sky_phone_company_requests`
            WHERE `id` = ? AND `revision` = ? AND `mutation_token` = ?
        ]]
        event_params = { event_id, access.row.status, request_id, revision + 1, mutation_token }
    else
        event_query = [[
            INSERT INTO `sky_phone_company_request_events`
                (`id`, `request_id`, `event_type`, `actor_type`, `actor_identifier`, `from_status`, `to_status`)
            SELECT ?, `id`, 'cancelled', 'company', ?, ?, 'cancelled'
            FROM `sky_phone_company_requests`
            WHERE `id` = ? AND `revision` = ? AND `mutation_token` = ?
        ]]
        event_params = {
            event_id,
            access.member.identifier,
            access.row.status,
            request_id,
            revision + 1,
            mutation_token,
        }
    end
    if not Bridge.Database.Transaction({
        {
            query = (([[
                UPDATE `sky_phone_company_requests`
                SET `status` = 'cancelled', `revision` = `revision` + 1,
                    `cancelled_at` = CURRENT_TIMESTAMP, `mutation_token` = ?%s
                WHERE `id` = ? AND `revision` = ? AND `status` = ?
            ]])):format(customer_unread_update),
            params = { mutation_token, request_id, revision, access.row.status },
        },
        { query = event_query, params = event_params },
    }) then
        return { success = false, error = "request_failed" }
    end
    local committed = Bridge.Database.Query(
        "SELECT `id` FROM `sky_phone_company_request_events` WHERE `id` = ? LIMIT 1",
        { event_id }
    )
    if not committed[1] then
        return { success = false, error = "revision_conflict" }
    end
    local row = request_row(request_id)
    emit_request_change(row, true, true, source)
    if actor_type == "customer" then
        notify_company(row.company_id, "sky_phone:companies:notification", notification_payload(
            "requestUpdated",
            "work",
            row
        ), source)
    else
        notify_sim(row.customer_sim_id, "sky_phone:companies:notification", notification_payload(
            "requestUpdated",
            "customer",
            row
        ))
    end
    local payload, payload_error = mutation_request_payload(source, request_id)
    if not payload then
        return payload_error
    end
    return { success = true, data = payload }
end)

Bridge.Callbacks.Register("sky_phone:companies:send-message", function(source, data)
    local allowed, rate_error = allow_mutation(source, "send_message", "Message")
    if not allowed then
        return rate_error
    end
    local request_id = type(data) == "table" and data.requestId or nil
    local revision = type(data) == "table" and valid_integer(data.revision, 1, 4294967295) or nil
    local body = type(data) == "table" and valid_text(data.body, Config.Companies.MessageMaxLength, false) or nil
    if not valid_uuid(request_id) or not revision or not body then
        return { success = false, error = "invalid_request" }
    end
    local access, access_error = request_access(source, request_id)
    if not access then
        return access_error
    end
    if terminal_statuses[access.row.status]
        or (access.audience == "company" and not can_handle_request(access))
    then
        return { success = false, error = "invalid_status" }
    end
    local message_id = uuid()
    local mutation_token = uuid()
    local new_status = access.audience == "customer" and access.row.status == "waiting_customer"
        and "in_progress" or access.row.status
    local audience_unread_update = access.audience == "customer"
        and ", `company_activity_revision` = `company_activity_revision` + 1"
        or ", `customer_unread` = `customer_unread` + 1"
    local statements = {
        {
            query = ([[
                UPDATE `sky_phone_company_requests`
                SET `status` = ?, `revision` = `revision` + 1, `mutation_token` = ?%s
                WHERE `id` = ? AND `revision` = ? AND `status` = ?
                    AND `status` NOT IN ('completed', 'cancelled')
            ]]):format(audience_unread_update),
            params = { new_status, mutation_token, request_id, revision, access.row.status },
        },
    }
    if access.audience == "customer" then
        statements[#statements + 1] = {
            query = [[
                INSERT INTO `sky_phone_company_request_messages`
                    (`id`, `request_id`, `sender_type`, `sender_sim_id`, `body`)
                SELECT ?, `id`, 'customer', ?, ? FROM `sky_phone_company_requests`
                WHERE `id` = ? AND `revision` = ? AND `mutation_token` = ?
            ]],
            params = { message_id, access.row.customer_sim_id, body, request_id, revision + 1, mutation_token },
        }
    else
        statements[#statements + 1] = {
            query = [[
                INSERT INTO `sky_phone_company_request_messages`
                    (`id`, `request_id`, `sender_type`, `sender_identifier`, `body`)
                SELECT ?, `id`, 'company', ?, ? FROM `sky_phone_company_requests`
                WHERE `id` = ? AND `revision` = ? AND `mutation_token` = ?
            ]],
            params = { message_id, access.member.identifier, body, request_id, revision + 1, mutation_token },
        }
    end
    if new_status ~= access.row.status then
        statements[#statements + 1] = {
            query = [[
                INSERT INTO `sky_phone_company_request_events`
                    (`id`, `request_id`, `event_type`, `actor_type`, `from_status`, `to_status`)
                SELECT ?, `id`, 'status', 'customer', ?, ? FROM `sky_phone_company_requests`
                WHERE `id` = ? AND `revision` = ? AND `mutation_token` = ?
            ]],
            params = { uuid(), access.row.status, new_status, request_id, revision + 1, mutation_token },
        }
    end
    if not Bridge.Database.Transaction(statements) then
        return { success = false, error = "request_failed" }
    end
    local inserted = Bridge.Database.Query(
        "SELECT `id` FROM `sky_phone_company_request_messages` WHERE `id` = ? LIMIT 1",
        { message_id }
    )
    if not inserted[1] then
        return { success = false, error = "revision_conflict" }
    end
    local row = request_row(request_id)
    emit_request_change(row, true, true, source)
    if access.audience == "customer" then
        local notification = notification_payload("newMessage", "work", row)
        if row.assigned_identifier then
            notify_identifier(
                row.assigned_identifier,
                row.company_id,
                "sky_phone:companies:notification",
                notification
            )
        end
    else
        notify_sim(row.customer_sim_id, "sky_phone:companies:notification", notification_payload(
            "newMessage",
            "customer",
            row
        ))
    end
    local payload, payload_error = mutation_request_payload(source, request_id)
    if not payload then
        return payload_error
    end
    return { success = true, data = payload }
end)

Bridge.Callbacks.Register("sky_phone:companies:claim-request", function(source, data)
    local allowed, rate_error = allow_mutation(source, "claim_request", "RequestAction")
    if not allowed then
        return rate_error
    end
    local member, member_error = require_permission(source, "WorkQueue")
    if not member then
        return member_error
    end
    local request_id = type(data) == "table" and data.requestId or nil
    local revision = type(data) == "table" and valid_integer(data.revision, 1, 4294967295) or nil
    if not valid_uuid(request_id) or not revision then
        return { success = false, error = "invalid_request" }
    end
    local mutation_token = uuid()
    local event_id = uuid()
    if not Bridge.Database.Transaction({
        {
            query = [[
                UPDATE `sky_phone_company_requests`
                SET `assigned_identifier` = ?, `status` = 'assigned', `revision` = `revision` + 1,
                    `customer_unread` = `customer_unread` + 1, `mutation_token` = ?
                WHERE `id` = ? AND `company_id` = ? AND `revision` = ?
                    AND `status` = 'new' AND `assigned_identifier` IS NULL
            ]],
            params = { member.identifier, mutation_token, request_id, member.company_id, revision },
        },
        {
            query = [[
                INSERT INTO `sky_phone_company_request_events`
                    (`id`, `request_id`, `event_type`, `actor_type`, `actor_identifier`, `from_status`, `to_status`)
                SELECT ?, `id`, 'assigned', 'company', ?, 'new', 'assigned'
                FROM `sky_phone_company_requests`
                WHERE `id` = ? AND `revision` = ? AND `mutation_token` = ?
            ]],
            params = { event_id, member.identifier, request_id, revision + 1, mutation_token },
        },
    }) then
        return { success = false, error = "request_failed" }
    end
    local committed = Bridge.Database.Query(
        "SELECT `id` FROM `sky_phone_company_request_events` WHERE `id` = ? LIMIT 1",
        { event_id }
    )
    if not committed[1] then
        local current = Bridge.Database.Query([[
            SELECT `id` FROM `sky_phone_company_requests`
            WHERE `id` = ? AND `company_id` = ?
            LIMIT 1
        ]], { request_id, member.company_id })
        return { success = false, error = current[1] and "revision_conflict" or "request_not_found" }
    end
    local row = request_row(request_id)
    emit_request_change(row, true, true, source)
    notify_sim(row.customer_sim_id, "sky_phone:companies:notification", notification_payload(
        "assigned",
        "customer",
        row
    ))
    local payload, payload_error = mutation_request_payload(source, request_id)
    if not payload then
        return payload_error
    end
    return { success = true, data = payload }
end)

local function resolve_member(member_id, company_id)
    if not valid_uuid(member_id) then
        return nil
    end
    local online = {}
    for _, player_source in ipairs(Bridge.Framework.GetPlayers()) do
        online[tonumber(player_source) or player_source] = true
    end
    for target, token in pairs(member_tokens) do
        if token.token == member_id and token.company_id == company_id and online[target]
            and os.time() - token.created_at <= 300
        then
            local target_member = membership(target)
            if not target_member or target_member.company_id ~= company_id
                or target_member.grade < permission_grade(target_member.definition, "WorkQueue")
            then
                return nil
            end
            local identifier = Bridge.Framework.GetIdentifier(target)
            if type(identifier) ~= "string" or identifier == "" or identifier ~= token.identifier then
                return nil
            end
            return { source = target, identifier = identifier }
        end
    end
    return nil
end

Bridge.Callbacks.Register("sky_phone:companies:assign-request", function(source, data)
    local allowed, rate_error = allow_mutation(source, "assign_request", "RequestAction")
    if not allowed then
        return rate_error
    end
    local member, member_error = require_permission(source, "Assign")
    if not member then
        return member_error
    end
    local request_id = type(data) == "table" and data.requestId or nil
    local revision = type(data) == "table" and valid_integer(data.revision, 1, 4294967295) or nil
    local target = type(data) == "table" and resolve_member(data.memberId, member.company_id) or nil
    if not valid_uuid(request_id) or not revision or not target then
        return { success = false, error = "invalid_request" }
    end
    local row = request_row(request_id)
    if not row or row.company_id ~= member.company_id then
        return { success = false, error = "request_not_found" }
    end
    if terminal_statuses[row.status] then
        return { success = false, error = "invalid_status" }
    end
    if row.assigned_identifier == target.identifier then
        return { success = false, error = "invalid_status" }
    end
    local next_status = row.status == "new" and "assigned" or row.status
    local mutation_token = uuid()
    local event_id = uuid()
    if not Bridge.Database.Transaction({
        {
            query = [[
                UPDATE `sky_phone_company_requests`
                SET `assigned_identifier` = ?, `status` = ?, `revision` = `revision` + 1,
                    `customer_unread` = `customer_unread` + 1,
                    `company_activity_revision` = `company_activity_revision` + 1,
                    `mutation_token` = ?
                WHERE `id` = ? AND `company_id` = ? AND `revision` = ? AND `status` = ?
                    AND `status` NOT IN ('completed', 'cancelled')
            ]],
            params = {
                target.identifier,
                next_status,
                mutation_token,
                request_id,
                member.company_id,
                revision,
                row.status,
            },
        },
        {
            query = [[
                INSERT INTO `sky_phone_company_request_events`
                    (`id`, `request_id`, `event_type`, `actor_type`, `actor_identifier`, `from_status`, `to_status`)
                SELECT ?, `id`, 'assigned', 'company', ?, ?, ?
                FROM `sky_phone_company_requests`
                WHERE `id` = ? AND `revision` = ? AND `mutation_token` = ?
            ]],
            params = {
                event_id,
                member.identifier,
                row.status,
                next_status,
                request_id,
                revision + 1,
                mutation_token,
            },
        },
    }) then
        return { success = false, error = "request_failed" }
    end
    local committed = Bridge.Database.Query(
        "SELECT `id` FROM `sky_phone_company_request_events` WHERE `id` = ? LIMIT 1",
        { event_id }
    )
    if not committed[1] then
        return { success = false, error = "revision_conflict" }
    end
    row = request_row(request_id)
    emit_request_change(row, true, true, source)
    notify_identifier(
        target.identifier,
        row.company_id,
        "sky_phone:companies:notification",
        notification_payload("assigned", "work", row)
    )
    notify_sim(row.customer_sim_id, "sky_phone:companies:notification", notification_payload(
        "assigned",
        "customer",
        row
    ))
    local payload, payload_error = mutation_request_payload(source, request_id)
    if not payload then
        return payload_error
    end
    return { success = true, data = payload }
end)

Bridge.Callbacks.Register("sky_phone:companies:update-request-status", function(source, data)
    local allowed, rate_error = allow_mutation(source, "update_request_status", "RequestAction")
    if not allowed then
        return rate_error
    end
    local request_id = type(data) == "table" and data.requestId or nil
    local revision = type(data) == "table" and valid_integer(data.revision, 1, 4294967295) or nil
    local status = type(data) == "table" and data.status or nil
    if not valid_uuid(request_id) or not revision or not Config.Companies.Statuses[status] then
        return { success = false, error = "invalid_request" }
    end
    local access, access_error = request_access(source, request_id)
    if not access then
        return access_error
    end
    if access.audience ~= "company" or not can_handle_request(access) then
        return { success = false, error = "not_authorized" }
    end
    if not status_transitions[access.row.status] or not status_transitions[access.row.status][status] then
        return { success = false, error = "invalid_status" }
    end
    local mutation_token = uuid()
    local event_id = uuid()
    if not Bridge.Database.Transaction({
        {
            query = [[
                UPDATE `sky_phone_company_requests`
                SET `status` = ?, `revision` = `revision` + 1, `customer_unread` = `customer_unread` + 1,
                    `completed_at` = CASE WHEN ? = 'completed' THEN CURRENT_TIMESTAMP ELSE `completed_at` END,
                    `cancelled_at` = CASE WHEN ? = 'cancelled' THEN CURRENT_TIMESTAMP ELSE `cancelled_at` END,
                    `mutation_token` = ?
                WHERE `id` = ? AND `company_id` = ? AND `revision` = ? AND `status` = ?
            ]],
            params = {
                status,
                status,
                status,
                mutation_token,
                request_id,
                access.row.company_id,
                revision,
                access.row.status,
            },
        },
        {
            query = [[
                INSERT INTO `sky_phone_company_request_events`
                    (`id`, `request_id`, `event_type`, `actor_type`, `actor_identifier`, `from_status`, `to_status`)
                SELECT ?, `id`, ?, 'company', ?, ?, ?
                FROM `sky_phone_company_requests`
                WHERE `id` = ? AND `revision` = ? AND `mutation_token` = ?
            ]],
            params = {
                event_id,
                status == "cancelled" and "cancelled" or "status",
                access.member.identifier,
                access.row.status,
                status,
                request_id,
                revision + 1,
                mutation_token,
            },
        },
    }) then
        return { success = false, error = "request_failed" }
    end
    local committed = Bridge.Database.Query(
        "SELECT `id` FROM `sky_phone_company_request_events` WHERE `id` = ? LIMIT 1",
        { event_id }
    )
    if not committed[1] then
        return { success = false, error = "revision_conflict" }
    end
    local row = request_row(request_id)
    emit_request_change(row, true, true, source)
    notify_sim(row.customer_sim_id, "sky_phone:companies:notification", notification_payload(
        "requestUpdated",
        "customer",
        row
    ))
    local payload, payload_error = mutation_request_payload(source, request_id)
    if not payload then
        return payload_error
    end
    return { success = true, data = payload }
end)

Bridge.Callbacks.Register("sky_phone:companies:call-customer", function(source, data)
    local allowed, rate_error = allow_mutation(source, "call_customer", "RequestAction")
    if not allowed then
        return rate_error
    end
    local request_id = type(data) == "table" and data.requestId or nil
    if not valid_uuid(request_id) then
        return { success = false, error = "invalid_request" }
    end
    local access, access_error = request_access(source, request_id)
    if not access then
        return access_error
    end
    if access.audience ~= "company" or not can_handle_request(access) or terminal_statuses[access.row.status] then
        return { success = false, error = "not_authorized" }
    end
    if not SkyPhoneCompanies.CanPlaceCompanyCall(source, access.row.company_id) then
        return { success = false, error = "not_authorized" }
    end
    local rows = Bridge.Database.Query([[
        SELECT sim.`phone_number`
        FROM `sky_phone_company_requests` request
        INNER JOIN `sky_phone_sims` sim ON sim.`id` = request.`customer_sim_id`
        WHERE request.`id` = ? AND request.`company_id` = ?
        LIMIT 1
    ]], { request_id, access.row.company_id })
    if not rows[1] then
        return { success = false, error = "call_unavailable" }
    end
    local result = SkyPhoneCalls.StartCompanyCall(source, access.row.company_id, rows[1].phone_number)
    if not result.success and (result.error == "recipient_unavailable" or result.error == "company_unavailable") then
        return { success = false, error = "call_unavailable" }
    end
    return result
end)

Bridge.Callbacks.Register("sky_phone:companies:dial-service-line", function(source, data)
    local allowed, rate_error = allow_mutation(source, "dial_service_line", "RequestAction")
    if not allowed then
        return rate_error
    end
    local phone_number = type(data) == "table" and data.phoneNumber or nil
    if type(phone_number) ~= "string" or phone_number == "" then
        return { success = false, error = "invalid_number" }
    end
    local member = call_member(source)
    if not member or member.definition.ServiceLine.CanCall ~= true then
        return { success = false, error = "not_authorized" }
    end
    return SkyPhoneCalls.StartCompanyCall(source, member.company_id, phone_number)
end)

local function company_mutation_payload(source, company_id)
    local company = company_payload(company_id, true)
    if not company then
        return nil
    end
    company.updatedAtUnix = nil
    return { company = company, context = work_context(source) }
end

local function audit_statement(company_id, identifier, action, target_type, target_id, mutation_token, audit_id)
    return {
        query = [[
            INSERT INTO `sky_phone_company_audit`
                (`id`, `company_id`, `actor_identifier`, `action`, `target_type`, `target_id`, `metadata`)
            SELECT ?, `company_id`, ?, ?, ?, ?, ?
            FROM `sky_phone_company_profiles`
            WHERE `company_id` = ? AND `mutation_token` = ?
        ]],
        params = {
            audit_id,
            identifier,
            action,
            target_type,
            target_id,
            json.encode({ revisionChecked = true }),
            company_id,
            mutation_token,
        },
    }
end

local function audit_committed(audit_id)
    local rows = Bridge.Database.Query([[
        SELECT `id` FROM `sky_phone_company_audit`
        WHERE `id` = ?
        LIMIT 1
    ]], { audit_id })
    return rows[1] ~= nil
end

Bridge.Callbacks.Register("sky_phone:companies:update-availability", function(source, data)
    local allowed, rate_error = allow_mutation(source, "update_availability", "Profile")
    if not allowed then
        return rate_error
    end
    local member, member_error = require_permission(source, "Availability")
    if not member then
        return member_error
    end
    local availability = type(data) == "table" and data.availability or nil
    local revision = type(data) == "table" and valid_integer(data.revision, 1, 4294967295) or nil
    if not Config.Companies.AvailabilityStatuses[availability] or not revision then
        return { success = false, error = "invalid_request" }
    end
    local expiry = parse_expiry(data.expiresAt, Config.Companies.AvailabilityMaximumSeconds)
    if expiry == false then
        return { success = false, error = "invalid_expiration" }
    end
    local mutation_token = uuid()
    local audit_id = uuid()
    local update_query
    local update_params
    if expiry then
        update_query = [[
            UPDATE `sky_phone_company_profiles`
            SET `availability` = ?, `availability_updated_by` = ?,
                `availability_updated_at` = CURRENT_TIMESTAMP,
                `availability_expires_at` = FROM_UNIXTIME(?),
                `revision` = `revision` + 1, `mutation_token` = ?
            WHERE `company_id` = ? AND `revision` = ?
        ]]
        update_params = { availability, member.identifier, expiry, mutation_token, member.company_id, revision }
    else
        update_query = [[
            UPDATE `sky_phone_company_profiles`
            SET `availability` = ?, `availability_updated_by` = ?,
                `availability_updated_at` = CURRENT_TIMESTAMP, `availability_expires_at` = NULL,
                `revision` = `revision` + 1, `mutation_token` = ?
            WHERE `company_id` = ? AND `revision` = ?
        ]]
        update_params = { availability, member.identifier, mutation_token, member.company_id, revision }
    end
    if not Bridge.Database.Transaction({
        { query = update_query, params = update_params },
        audit_statement(
            member.company_id,
            member.identifier,
            "update_availability",
            "profile",
            member.company_id,
            mutation_token,
            audit_id
        ),
    }) then
        return { success = false, error = "request_failed" }
    end
    if not audit_committed(audit_id) then
        return { success = false, error = "revision_conflict" }
    end
    emit_public_change(member.company_id)
    return { success = true, data = company_mutation_payload(source, member.company_id) }
end)

local function media_id_for_profile(source, value)
    local media_id = valid_integer(value, 1, 9007199254740991)
    if not media_id or not SkyPhoneMedia.ResolveOwnedMedia(source, media_id, "photo") then
        return nil
    end
    return media_id
end

Bridge.Callbacks.Register("sky_phone:companies:update-profile", function(source, data)
    local allowed, rate_error = allow_mutation(source, "update_profile", "Profile")
    if not allowed then
        return rate_error
    end
    local member, member_error = require_permission(source, "Profile")
    if not member then
        return member_error
    end
    if type(data) ~= "table" then
        return { success = false, error = "invalid_request" }
    end
    local revision = valid_integer(data.revision, 1, 4294967295)
    local description = valid_text(data.description, Config.Companies.ProfileDescriptionMaxLength, true)
    local district = valid_text(data.district, Config.Companies.DistrictMaxLength, true)
    local location_label = valid_text(data.locationLabel or "", Config.Companies.DistrictMaxLength, true)
    local address = valid_text(data.address, Config.Companies.AddressMaxLength, true)
    if not revision or not description or not district or not location_label or not address
        or type(data.acceptsRequests) ~= "boolean"
        or (member.definition.Emergency and data.acceptsRequests)
    then
        return { success = false, error = "invalid_profile" }
    end
    if data.phoneNumber ~= nil then
        local number = SkyPhoneSimNumber.NormalizeService(data.phoneNumber, Config.Sim.NumberLength)
        if number ~= member.definition.ServiceLine.Number then
            return { success = false, error = "invalid_profile" }
        end
    end
    local set_parts = {
        "`description` = ?",
        "`district` = ?",
        "`location_label` = ?",
        "`address` = ?",
        "`accepts_requests` = ?",
    }
    local parameters = { description, district, location_label, address, data.acceptsRequests and 1 or 0 }
    if data.coords ~= nil then
        if type(data.coords) ~= "table" then
            return { success = false, error = "invalid_profile" }
        end
        local x = tonumber(data.coords.x)
        local y = tonumber(data.coords.y)
        local z = tonumber(data.coords.z)
        if not x or not y or not z or x ~= x or y ~= y or z ~= z
            or math.abs(x) > 10000 or math.abs(y) > 10000 or math.abs(z) > 2000
        then
            return { success = false, error = "invalid_profile" }
        end
        set_parts[#set_parts + 1] = "`location_x` = ?"
        set_parts[#set_parts + 1] = "`location_y` = ?"
        set_parts[#set_parts + 1] = "`location_z` = ?"
        parameters[#parameters + 1] = x
        parameters[#parameters + 1] = y
        parameters[#parameters + 1] = z
    end
    for _, media_field in ipairs({
        { input = "logoMediaId", column = "logo_media_id" },
        { input = "coverMediaId", column = "cover_media_id" },
    }) do
        if data[media_field.input] ~= nil then
            local media_id = media_id_for_profile(source, data[media_field.input])
            if not media_id then
                return { success = false, error = "invalid_media" }
            end
            set_parts[#set_parts + 1] = ("`%s` = ?"):format(media_field.column)
            parameters[#parameters + 1] = media_id
        end
    end
    local mutation_token = uuid()
    local audit_id = uuid()
    set_parts[#set_parts + 1] = "`revision` = `revision` + 1"
    set_parts[#set_parts + 1] = "`mutation_token` = ?"
    parameters[#parameters + 1] = mutation_token
    parameters[#parameters + 1] = member.company_id
    parameters[#parameters + 1] = revision
    if not Bridge.Database.Transaction({
        {
            query = ("UPDATE `sky_phone_company_profiles` SET %s WHERE `company_id` = ? AND `revision` = ?")
                :format(table.concat(set_parts, ", ")),
            params = parameters,
        },
        audit_statement(
            member.company_id,
            member.identifier,
            "update_profile",
            "profile",
            member.company_id,
            mutation_token,
            audit_id
        ),
    }) then
        return { success = false, error = "request_failed" }
    end
    if not audit_committed(audit_id) then
        return { success = false, error = "revision_conflict" }
    end
    emit_public_change(member.company_id)
    return { success = true, data = company_mutation_payload(source, member.company_id) }
end)

local function valid_clock(value)
    if type(value) ~= "string" then
        return false
    end
    local hour, minute = value:match("^(%d%d):(%d%d)$")
    hour = tonumber(hour)
    minute = tonumber(minute)
    return hour and minute and hour <= 23 and minute <= 59
end

Bridge.Callbacks.Register("sky_phone:companies:update-hours", function(source, data)
    local allowed, rate_error = allow_mutation(source, "update_hours", "Profile")
    if not allowed then
        return rate_error
    end
    local member, member_error = require_permission(source, "Hours")
    if not member then
        return member_error
    end
    local revision = type(data) == "table" and valid_integer(data.revision, 1, 4294967295) or nil
    local hours = type(data) == "table" and data.hours or nil
    if not revision or not valid_array(hours, 7) then
        return { success = false, error = "invalid_profile" }
    end
    local seen_days = {}
    for _, entry in ipairs(hours) do
        local day = type(entry) == "table" and valid_integer(entry.day, 0, 6) or nil
        if not day or seen_days[day] or type(entry.isClosed) ~= "boolean"
            or (not entry.isClosed and (not valid_clock(entry.opensAt) or not valid_clock(entry.closesAt)
                or entry.opensAt == entry.closesAt))
        then
            return { success = false, error = "invalid_profile" }
        end
        seen_days[day] = true
    end
    local mutation_token = uuid()
    local audit_id = uuid()
    local statements = {
        {
            query = [[
                UPDATE `sky_phone_company_profiles`
                SET `revision` = `revision` + 1, `mutation_token` = ?
                WHERE `company_id` = ? AND `revision` = ?
            ]],
            params = { mutation_token, member.company_id, revision },
        },
        {
            query = [[
                DELETE hours FROM `sky_phone_company_hours` hours
                INNER JOIN `sky_phone_company_profiles` profile ON profile.`company_id` = hours.`company_id`
                WHERE hours.`company_id` = ? AND profile.`mutation_token` = ?
            ]],
            params = { member.company_id, mutation_token },
        },
    }
    for _, entry in ipairs(hours) do
        local query
        local params
        if entry.isClosed then
            query = [[
                INSERT INTO `sky_phone_company_hours` (`company_id`, `weekday`, `is_closed`)
                SELECT `company_id`, ?, 1 FROM `sky_phone_company_profiles`
                WHERE `company_id` = ? AND `mutation_token` = ?
            ]]
            params = { entry.day, member.company_id, mutation_token }
        else
            query = [[
                INSERT INTO `sky_phone_company_hours`
                    (`company_id`, `weekday`, `is_closed`, `opens_at`, `closes_at`)
                SELECT `company_id`, ?, 0, ?, ? FROM `sky_phone_company_profiles`
                WHERE `company_id` = ? AND `mutation_token` = ?
            ]]
            params = { entry.day, entry.opensAt, entry.closesAt, member.company_id, mutation_token }
        end
        statements[#statements + 1] = { query = query, params = params }
    end
    statements[#statements + 1] = audit_statement(
        member.company_id,
        member.identifier,
        "update_hours",
        "hours",
        member.company_id,
        mutation_token,
        audit_id
    )
    if not Bridge.Database.Transaction(statements) then
        return { success = false, error = "request_failed" }
    end
    if not audit_committed(audit_id) then
        return { success = false, error = "revision_conflict" }
    end
    emit_public_change(member.company_id)
    return { success = true, data = company_mutation_payload(source, member.company_id) }
end)

Bridge.Callbacks.Register("sky_phone:companies:update-services", function(source, data)
    local allowed, rate_error = allow_mutation(source, "update_services", "Profile")
    if not allowed then
        return rate_error
    end
    local member, member_error = require_permission(source, "Services")
    if not member then
        return member_error
    end
    local revision = type(data) == "table" and valid_integer(data.revision, 1, 4294967295) or nil
    local services = type(data) == "table" and data.services or nil
    if not revision or not valid_array(services, Config.Companies.MaximumServices) then
        return { success = false, error = "invalid_profile" }
    end
    local existing_rows = Bridge.Database.Query(
        "SELECT `id` FROM `sky_phone_company_services` WHERE `company_id` = ? AND `archived` = 0",
        { member.company_id }
    )
    local existing = {}
    for _, row in ipairs(existing_rows) do
        existing[row.id] = true
    end
    local normalized = {}
    local seen = {}
    for index, service in ipairs(services) do
        if type(service) ~= "table" or type(service.active) ~= "boolean"
            or type(service.acceptsRequests) ~= "boolean"
        then
            return { success = false, error = "invalid_profile" }
        end
        local title = valid_text(service.title, Config.Companies.ServiceTitleMaxLength, false)
        local description = valid_text(
            service.description or "",
            Config.Companies.ServiceDescriptionMaxLength,
            true
        )
        local price = service.priceText == nil and ""
            or valid_text(service.priceText, Config.Companies.ServicePriceMaxLength, true)
        if not title or not description or not price then
            return { success = false, error = "invalid_profile" }
        end
        local service_id = valid_service_id(service.id) and existing[service.id] and service.id or uuid()
        if seen[service_id] then
            return { success = false, error = "invalid_profile" }
        end
        seen[service_id] = true
        normalized[#normalized + 1] = {
            id = service_id,
            title = title,
            description = description,
            price = price,
            accepts_requests = service.acceptsRequests,
            active = service.active,
            sort_order = index,
        }
    end
    local mutation_token = uuid()
    local audit_id = uuid()
    local statements = {
        {
            query = [[
                UPDATE `sky_phone_company_profiles`
                SET `revision` = `revision` + 1, `mutation_token` = ?
                WHERE `company_id` = ? AND `revision` = ?
            ]],
            params = { mutation_token, member.company_id, revision },
        },
        {
            query = [[
                UPDATE `sky_phone_company_services` service
                INNER JOIN `sky_phone_company_profiles` profile ON profile.`company_id` = service.`company_id`
                SET service.`active` = 0, service.`requests_enabled` = 0, service.`archived` = 1
                WHERE service.`company_id` = ? AND profile.`mutation_token` = ?
            ]],
            params = { member.company_id, mutation_token },
        },
    }
    for _, service in ipairs(normalized) do
        statements[#statements + 1] = {
            query = [[
                INSERT INTO `sky_phone_company_services`
                    (`id`, `company_id`, `title`, `description`, `price_text`, `requests_enabled`, `active`, `sort_order`)
                SELECT ?, `company_id`, ?, ?, ?, ?, ?, ? FROM `sky_phone_company_profiles`
                WHERE `company_id` = ? AND `mutation_token` = ?
                ON DUPLICATE KEY UPDATE
                    `title` = VALUES(`title`), `description` = VALUES(`description`),
                    `price_text` = VALUES(`price_text`), `requests_enabled` = VALUES(`requests_enabled`),
                    `active` = VALUES(`active`), `archived` = 0, `sort_order` = VALUES(`sort_order`)
            ]],
            params = {
                service.id,
                service.title,
                service.description,
                service.price,
                service.accepts_requests and 1 or 0,
                service.active and 1 or 0,
                service.sort_order,
                member.company_id,
                mutation_token,
            },
        }
    end
    statements[#statements + 1] = audit_statement(
        member.company_id,
        member.identifier,
        "update_services",
        "services",
        member.company_id,
        mutation_token,
        audit_id
    )
    if not Bridge.Database.Transaction(statements) then
        return { success = false, error = "request_failed" }
    end
    if not audit_committed(audit_id) then
        return { success = false, error = "revision_conflict" }
    end
    emit_public_change(member.company_id)
    return { success = true, data = company_mutation_payload(source, member.company_id) }
end)

Bridge.Callbacks.Register("sky_phone:companies:publish-announcement", function(source, data)
    local allowed, rate_error = allow_mutation(source, "publish_announcement", "Profile")
    if not allowed then
        return rate_error
    end
    local member, member_error = require_permission(source, "Announcement")
    if not member then
        return member_error
    end
    local revision = type(data) == "table" and valid_integer(data.revision, 1, 4294967295) or nil
    local body = type(data) == "table"
        and valid_text(data.body or "", Config.Companies.AnnouncementBodyMaxLength, true) or nil
    if not revision or body == nil then
        return { success = false, error = "invalid_profile" }
    end
    local expiry = parse_expiry(data.expiresAt, Config.Companies.AnnouncementMaximumSeconds)
    if expiry == false then
        return { success = false, error = "invalid_expiration" }
    end
    local mutation_token = uuid()
    local audit_id = uuid()
    local statements = {
        {
            query = [[
                UPDATE `sky_phone_company_profiles`
                SET `revision` = `revision` + 1, `mutation_token` = ?
                WHERE `company_id` = ? AND `revision` = ?
            ]],
            params = { mutation_token, member.company_id, revision },
        },
        {
            query = [[
                UPDATE `sky_phone_company_announcements` announcement
                INNER JOIN `sky_phone_company_profiles` profile ON profile.`company_id` = announcement.`company_id`
                SET announcement.`active` = 0
                WHERE announcement.`company_id` = ? AND profile.`mutation_token` = ?
            ]],
            params = { member.company_id, mutation_token },
        },
    }
    if body ~= "" then
        local insert_query
        local insert_params
        if expiry then
            insert_query = [[
                INSERT INTO `sky_phone_company_announcements`
                    (`id`, `company_id`, `title`, `body`, `created_by`, `expires_at`)
                SELECT ?, `company_id`, '', ?, ?, FROM_UNIXTIME(?) FROM `sky_phone_company_profiles`
                WHERE `company_id` = ? AND `mutation_token` = ?
            ]]
            insert_params = { uuid(), body, member.identifier, expiry, member.company_id, mutation_token }
        else
            insert_query = [[
                INSERT INTO `sky_phone_company_announcements`
                    (`id`, `company_id`, `title`, `body`, `created_by`)
                SELECT ?, `company_id`, '', ?, ? FROM `sky_phone_company_profiles`
                WHERE `company_id` = ? AND `mutation_token` = ?
            ]]
            insert_params = { uuid(), body, member.identifier, member.company_id, mutation_token }
        end
        statements[#statements + 1] = { query = insert_query, params = insert_params }
    end
    statements[#statements + 1] = audit_statement(
        member.company_id,
        member.identifier,
        "publish_announcement",
        "announcement",
        member.company_id,
        mutation_token,
        audit_id
    )
    if not Bridge.Database.Transaction(statements) then
        return { success = false, error = "request_failed" }
    end
    if not audit_committed(audit_id) then
        return { success = false, error = "revision_conflict" }
    end
    emit_public_change(member.company_id)
    return { success = true, data = company_mutation_payload(source, member.company_id) }
end)

Bridge.Callbacks.Register("sky_phone:companies:set-call-availability", function(source, data)
    local allowed, rate_error = allow_mutation(source, "set_call_availability", "CallAvailability")
    if not allowed then
        return rate_error
    end
    if type(data) ~= "table" or type(data.available) ~= "boolean" then
        return { success = false, error = "invalid_request" }
    end
    if not data.available then
        SkyPhoneCompanies.ClearCallAvailability(source)
        return { success = true, data = { context = work_context(source) } }
    end
    local member = call_member(source)
    if not member or not member.definition.ServiceLine.CanCall then
        return { success = false, error = "not_authorized" }
    end
    local device, device_error = current_device(source, true)
    if not device then
        return device_error
    end
    call_availability[source] = {
        company_id = member.company_id,
        sim_id = device.sim_id,
        imei = device.imei,
    }
    return { success = true, data = { context = work_context(source) } }
end)

AddEventHandler("playerDropped", function()
    SkyPhoneCompanies.ClearCallAvailability(source)
    member_tokens[source] = nil
end)

AddEventHandler("onResourceStop", function(resource_name)
    if resource_name ~= GetCurrentResourceName() then
        return
    end
    call_availability = {}
    round_robin_positions = {}
    member_tokens = {}
end)
end)
