Documentation for this module may be created at Module:InfoboxTV/doc

local p = {}

-- Helper function to trim whitespace from a string
local function trimWhitespace(s)
    if type(s) ~= 'string' then return '' end
    return s:match('^%s*(.-)%s*$')
end

-- Retrieve arguments from the frame and its parent
local function getArgs(frame)
    local args = {}
    local parent = frame:getParent()
    
    if parent and parent.args then
        for k, v in pairs(parent.args) do
            args[k] = trimWhitespace(v)
        end
    end
    
    for k, v in pairs(frame.args) do
        args[k] = trimWhitespace(v)
    end
    
    return args
end

-- Make a request to Wikidata for a specific property of an entity
local function makeRequest(entityId, property)
    if not mw.wikibase then
        return "This module requires mw.wikibase, which is unavailable on this wiki."
    end
    
    local success, result = pcall(function()
        return mw.wikibase.getEntity(entityId)
    end)
    
    if success and result and result.claims then
        local claims = result.claims[property] or {}
        for _, claim in pairs(claims) do
            if claim.mainsnak.snaktype == 'value' then
                local datavalue = claim.mainsnak.datavalue
                if datavalue.type == 'string' then
                    return datavalue.value
                elseif datavalue.type == 'wikibase-entityid' then
                    local label = mw.wikibase.getLabel(datavalue.value.id)
                    return label
                elseif datavalue.type == 'quantity' then
                    return datavalue.value.amount
                end
            end
        end
    end
    return nil
end

-- Get the value from Wikidata or return nil if not found
local function getWikidataValue(property, entityId)
    if not mw.wikibase then
        return nil
    end

    if not entityId then
        entityId = mw.wikibase.getEntityIdForCurrentPage()
    end
    if not entityId then return nil end
    
    return makeRequest(entityId, property)
end

-- Helper function to check if a value exists and is not empty
local function exists(var)
    return var ~= nil and var ~= ''
end

-- Function to get either a manual parameter or a Wikidata value
local function getValueOrWikidata(args, paramName, property)
    local value = args[paramName]
    if value then
        value = trimWhitespace(value)
    end
    if not exists(value) then
        value = getWikidataValue(property)
    end
    return value
end

-- Main infobox function
function p.main(frame)
    local args = getArgs(frame)
    
    local infobox = mw.html.create('table')
    infobox:css({
        ['border'] = '1px solid #aaa',
        ['background-color'] = '#f9f9f9',
        ['color'] = 'black',
        ['margin-bottom'] = '0.5em',
        ['margin-left'] = '1em',
        ['padding'] = '0.2em',
        ['float'] = 'right',
        ['clear'] = 'right',
        ['font-size'] = '88%',
        ['width'] = '22em',
    })
    
    -- Header row
    local header = infobox:tag('tr')
    header:tag('th')
        :attr('colspan', 2)
        :wikitext(getValueOrWikidata(args, 'ⴰⵣⵡⵍ', 'P1476') or mw.title.getCurrentTitle().text)
        :css({
            ['background-color'] = '#ccd2d9',
            ['padding'] = '0.4em',
            ['text-align'] = 'center',
            ['font-weight'] = 'bold',
        })
    
   -- Image
local image = getValueOrWikidata(args, 'ⵜⴰⵡⵍⴰⴼⵜ', 'P18')
if exists(image) then
    local imageRow = infobox:tag('tr')
    imageRow:tag('td')
        :attr('colspan', 2)
        :wikitext(string.format('[[File:%s|%s|%s]]', 
            image, 
            args.image_size or '250px', 
            args.image_alt or ''))
        :css({
            ['text-align'] = 'center', 
            ['padding'] = '0.5em' 
        })
    
    -- Caption
    local caption = getValueOrWikidata(args, 'ⴰⵣⵡⵍ_ⵜⴰⵡⵍⴰⴼⵜ', 'P2480')
    if exists(caption) then
        local captionRow = infobox:tag('tr')
        captionRow:tag('td')
            :attr('colspan', 2)
            :wikitext(caption)
            :css({
            	['text-align'] = 'center',
                ['padding'] = '0.2em',
                ['font-style'] = 'italic',
            })
    end
end
    
    -- Define sections with property groups
    local sections = {
        {
            title = 'ⵓⵎⵍⴰⵏ ⵉⵎⴰⵜⴰⵢⵏ',
            properties = {
                { 'ⵉⵙⵎ ⴰⵙⴰⵍⴰⵏ', 'ⵉⵙⵎ_ⴰⵙⴰⵍⴰⵏ', 'P1705' },
                { 'ⴰⵏⴰⵡ', 'ⴰⵏⴰⵡ', 'P136' },
                { 'ⵉⵙⴷⴷⵉⵜⵏ', 'ⵉⵙⴷⴷⵉⵜⵏ', 'P179' },
                { 'ⵉⵎⵔⵙⵉ', 'ⵉⵎⵔⵙⵉ', 'P921' },
                { 'ⵜⴰⵎⵓⵔⵜ', 'ⵜⴰⵎⵓⵔⵜ', 'P17' },
		        { 'ⵜⵓⵜⵍⴰⵢⵜ', 'ⵜⵓⵜⵍⴰⵢⵜ', 'P364' },
		        { 'ⴰⵎⴹⴰⵏ ⵏ ⵉⵎⵉⵔⵏ', 'ⴰⵎⴹⴰⵏ_ⵉⵎⵉⵔⵏ', 'P1113' },
		        { 'ⴰⵎⴹⴰⵏ ⵏ ⵉⵙⴷⴷⵉⵜⵏ', 'ⴰⵎⴹⴰⵏ_ⵉⵙⴷⴷⵉⵜⵏ', 'P1428' },
            }
        },
        {
            title = 'ⴰⴼⴰⵔⵙ',
            properties = {
                { 'ⴰⵎⴼⴰⵔⵙ', 'ⴰⵎⴼⴰⵔⵙ', 'P162' },
                { 'ⴰⵎⴼⴰⵔⵙ ⴰⵎⵣⵣⴳⵉⵔ', 'ⴰⵎⴼⴰⵔⵙ_ⴰⵎⵣⵣⴳⵉⵔ', 'P162' },
                { 'ⴰⵎⵙⵙⵓⴼⵖ', 'ⴰⵎⵙⵙⵓⴼⵖ', 'P57' },
                { 'ⴰⵙⵉⵏⴰⵕⵢⵓ', 'ⴰⵙⵉⵏⴰⵕⵢⵓ', 'P58' },
                { 'ⴰⵎⴰⵍⵍⴰⵙ', 'ⴰⵎⴰⵍⵍⴰⵙ', 'P725' },
                { 'ⴰⵙⵓⵍⴼ', 'ⴰⵙⵓⵍⴼ', 'P344' },
                { 'ⴰⵏⴹⴹⴰⵎ', 'ⴰⵏⴹⴹⴰⵎ', 'P86' },
                { 'ⵜⴰⵎⵙⵙⵓⵔⵜ ⵏ ⵓⴼⴰⵔⵙ', 'ⵜⴰⵎⵙⵙⵓⵔⵜ_ⴰⴼⴰⵔⵙ', 'P272' },
            }
        },
        {
            title = 'ⵓⴼⵓⵖ',
            properties = {
                { 'ⵜⵓⵜⵍⴰⵢⵜ ⵜⴰⵙⴰⵍⴰⵏⵜ', 'ⵜⵓⵜⵍⴰⵢⵜ_ⵜⴰⵙⴰⵍⴰⵏⵜ', 'P364' },
                { 'ⴰⵎⴹⴰⵏ ⵏ ⵜⵅⵔⵙⵉⵏ', 'ⴰⵎⴹⴰⵏ_ⵜⵉⵅⵔⵙⴰⵉⵏ', 'P1113' },
                { 'ⴰⵥⵟⵟⴰ', 'ⴰⵥⵟⵟⴰ', 'P473' },
                { 'ⴰⵣⵓⵣⵣⵔ ⴰⵎⵣⵡⴰⵔⵓ', 'ⴰⵣⵓⵣⵣⵔ_ⴰⵎⵣⵡⴰⵔⵓ', 'P577' },
				{ 'ⴰⵣⵓⵣⵣⵔ ⴰⵎⴳⴳⴰⵔⵓ', 'ⴰⵣⵓⵣⵣⵔ_ⴰⵎⴳⴳⴰⵔⵓ', 'P580' }
            }
        },
        {
            title = 'ⵉⵙⵖⵓⵏⵏ ⵉⴱⵕⵕⴰⵏⵉⵢⵏ',
            properties = {
                { 'ⴰⵙⵉⵜ ⴰⵎⴰⴷⴷⵓⴷ', 'ⴰⵙⵉⵜ_ⴰⵎⴰⴷⴷⵓⴷ', 'P856' },
                { 'IMDb', 'imdb', 'P345' },
                { 'TV.com', 'tv_com', 'P1874' }
            }
        }
    }
    
    -- Loop through sections and add them only if there are values for properties
    for _, section in ipairs(sections) do
        local hasContent = false
        local sectionContent = mw.html.create('')  -- Temporary storage for section content

        for _, prop in ipairs(section.properties) do
            local displayName, paramName, propertyId = unpack(prop)
            local value = getValueOrWikidata(args, paramName, propertyId)
            
            if exists(value) then
                hasContent = true
                local row = sectionContent:tag('tr')
                row:tag('th')
                    :wikitext(displayName)
                    :css({
                        ['background-color'] = '#f1f1f1',
                        ['padding'] = '0.2em',
                        ['text-align'] = 'left',
                        ['font-weight'] = 'bold',
                    })
                row:tag('td')
                    :wikitext(value)
                    :css({
                        ['padding'] = '0.2em',
                    })
            end
        end

        -- Add the section title and content if there's at least one property with a value
        if hasContent then
            infobox:tag('tr')
                :tag('th')
                :attr('colspan', 2)
                :wikitext(section.title)
                :css({
                    ['background-color'] = '#ddd',
                    ['padding'] = '0.4em',
                    ['text-align'] = 'center',
                    ['font-weight'] = 'bold',
                })
            infobox:node(sectionContent)
        end
    end

    return tostring(infobox)
end

return p