require('strict')

local getArgs = require("Module:Arguments").getArgs
local yesno = require("Module:Yesno")
local p = {}

local function list(args)
    local _args = {}
	
    local args = args
    if type(args) == 'nil' then
        args = {}
    elseif type(args) == 'string' then
        args = { args }
    end

    for _, v in ipairs(args) do
        table.insert(_args, v)
    end
	
    return '[ ' .. table.concat(_args, ', ') .. ' ]'
end

local function dict(args)
    local _args = {}
	
    local args = args
    if type(args) == 'nil' then
        args = {}
    elseif type(args) == 'string' then
        args = { args }
    end

    for i, v in pairs(args) do
        table.insert(_args, string.format('"%s" : %s', i, v))
    end
	
    return '{ ' .. table.concat(_args, ', ') .. ' }'
end

local function str(args)
    return '"' .. (args or '') .. '"'
end

local function get_page_count_by_category(category_name)
    return mw.getCurrentFrame():callParserFunction {
        name = 'PAGESINCATEGORY',
        args = { category_name, 'pages', 'R' }
    }
end

local function get_data_by_class(args)
    
    -- Class information
        
    local default_classes = {'fa', 'fl', 'a', 'ga', 'b', 'c', 'start', 'stub', 'list', 'unassessed'}

    local class_list = {
        ['fa'] = { ['name'] = { ['hans'] = '典范级', ['hant'] = '典範級' }, ['color'] = '#9CBDFF' },
        ['fl'] = { ['name'] = { ['hans'] = '特色列表级', ['hant'] = '特色列表級' }, ['color'] = '#9CBDFF' },
        ['a'] = { ['name'] = { ['hans'] = '甲级', ['hant'] = '甲級' }, ['color'] = '#66FFFF' },
        ['al'] = { ['name'] = { ['hans'] = '甲级列表级', ['hant'] = '甲級列表級' }, ['color'] = '#66FFFF' },
        ['ga'] = { ['name'] = { ['hans'] = '优良级', ['hant'] = '優良級' }, ['color'] = '#66FF66' },
        ['b'] = { ['name'] = { ['hans'] = '乙级', ['hant'] = '乙級' }, ['color'] = '#B2FF66' },
        ['bl'] = { ['name'] = { ['hans'] = '乙级列表级', ['hant'] = '乙級列表級' }, ['color'] = '#B2FF66' },
        ['c'] = { ['name'] = { ['hans'] = '丙级', ['hant'] = '丙級' }, ['color'] = '#FFFF66' },
        ['cl'] = { ['name'] = { ['hans'] = '丙级列表级', ['hant'] = '丙級列表級' }, ['color'] = '#FFFF66' },
        ['start'] = { ['name'] = { ['hans'] = '初级', ['hant'] = '初級' }, ['color'] = '#FFAA66' },
        ['list'] = { ['name'] = { ['hans'] = '列表级', ['hant'] = '列表級' }, ['color'] = '#C7B1FF' },
        ['stub'] = { ['name'] = { ['hans'] = '小作品级', ['hant'] = '小作品級' }, ['color'] = '#FFA4A4' },
        ['sl'] = { ['name'] = { ['hans'] = '小列表级', ['hant'] = '小列表級' }, ['color'] = '#FFA4A4' },
        ['unassessed'] = { ['name'] = { ['hans'] = '未评级', ['hant'] = '未評級' }, ['color'] = '#BEBEBE' },
    }
    
    if args.customclass then
        local custom_classes = mw.text.split(args.customclass:gsub('%s', ''), ';')
        for _, v in ipairs(custom_classes) do
            local tab = mw.text.split(v:lower():gsub('%s', ''), ':'), "", "", ""
            class_list[tab[1]] = {
                ['name'] = { ['hans'] = tab[2], ['hant'] = tab[3] },
                ['color'] = tab[4]
            }
        end
    end
    

    local ret = {}
    
    local topic = args.topic or ''
    
    local classes = {}
    if args.class then
        classes = mw.text.split(args.class:lower():gsub('%s', ''), ',')
    else
        classes = default_classes
    end
    
    local counts = {}
    if args.count then
        counts = mw.text.split(args.count:gsub('%s', ''), ',')
    end

    for i, v in ipairs(classes) do
        local info = class_list[v]
        local count, cat
        if #counts == 0 then
            cat = info.name.hans .. topic .. '条目'
            count = get_page_count_by_category(cat)
        else
            count = counts[i] or '0'
        end
        if yesno(args.hidezero) and count == '0' then
            -- pass
        else
            table.insert(ret, {
                ['name'] = info.name,
                ['color'] = info.color,
                ['count'] = count,
            })
        end
    end

    return ret
end

local function build_graph(title, height, width, pie_radius, data, variant)
    local temp_tab = {}

    -- graph
    local graph = {
        ['version'] = 2,
        ['axes'] = list(),
        ['height'] = height or '300',
        ['width'] = width or '300',
        ['padding'] = str('padding'),
    }

    -- graph['legends']
    graph['legends'] = list(dict{
        ['fill'] = str('color'),
        ['offset'] = '20',
        ['properties'] = dict(),
        ['title'] = str(title or ''),
    })

    -- graph['marks']
    graph['marks'] = list(dict{
        ['type'] = str('arc'),
        ['from'] = dict{
            ['data'] = str('table'),
            ['transform'] = list(dict{
                ['type'] = str('pie'),
                ['field'] = str('val'),
            }),
        },
        ['properties'] = dict{
            ['enter'] = dict{
                ['x'] = dict{
                    ['field'] = dict{ ['group'] = str('width'), },
                    ['mult'] = '0.5',
                },
                ['y'] = dict{
                    ['field'] = dict{ ['group'] = str('width'), },
                    ['mult'] = '0.5',
                },
                ['startAngle'] = dict{ ['field'] = str('layout_start'), },
                ['endAngle'] = dict{ ['field'] = str('layout_end'), },
                ['fill'] = dict{
                    ['field'] = str('idx'),
                    ['scale'] = str('color'),
                },
                ['innerRadius'] = dict{ ['value'] = '0', },
                ['outerRadius'] = dict{ ['value'] = pie_radius or '125', },
            },
        },
    })

    -- graph['data']
	local variant = (variant ~= 'hant' and 'hans' or 'hant')
    for _, v in ipairs(data) do
        table.insert(temp_tab, dict{
            ['col'] = str('data'),
            ['idx'] = str(v.name[variant] .. ':' .. mw.language.new('en'):formatNum(tonumber(v.count))),
            ['val'] = v.count,
        })
    end
    graph['data'] = list(dict{
        ['name'] = str('table'),
        ['values'] = list(temp_tab),
    })
    temp_tab = {}

    -- graph['scales']
    for _, v in ipairs(data) do
        table.insert(temp_tab, str(v.color))
    end
    graph['scales'] = list(dict{
        ['domain'] = dict{
            ['data'] = str('table'),
            ['field'] = str('idx'),
        },
        ['name'] = str('color'),
        ['type'] = str('ordinal'),
        ['range'] = list(temp_tab),
    })
    temp_tab = {}

    return mw.getCurrentFrame():extensionTag {
        ['name'] = 'graph',
        ['content'] = dict(graph),
    }
end

function p.main(frame)
    local args = getArgs(frame)
    return p._main(args)
end

function p._main(args)
    local hans_title = (args['topic-hans'] or args['topic'] .. '专题') .. '条目品质统计'
    local hant_title = (args['topic-hant'] or args['topic'] .. '專題') .. '條目品質統計'

    local height, width, radius = args.height, args.width, args.radius
    local data = get_data_by_class(args)

    return require( 'Module:WikitextLC' ).selective { 
        ['zh-hans'] = build_graph(hans_title, height, width, radius, data, 'hans'),
        ['zh-hant'] = build_graph(hant_title, height, width, radius, data, 'hant'),
    }
end

return p