namespace RealCV.Application.Data;

/// <summary>
/// List of recognised UK higher education institutions.
/// Source: GOV.UK Register of Higher Education Providers
/// </summary>
public static class UKInstitutions
{
    /// <summary>
    /// Recognised UK universities and higher education providers.
    /// These are legitimate degree-awarding institutions.
    /// </summary>
    public static readonly HashSet<string> RecognisedInstitutions = new(StringComparer.OrdinalIgnoreCase)
    {
        // Russell Group Universities
        "University of Birmingham",
        "University of Bristol",
        "University of Cambridge",
        "Cardiff University",
        "Durham University",
        "University of Edinburgh",
        "University of Exeter",
        "University of Glasgow",
        "Imperial College London",
        "King's College London",
        "University of Leeds",
        "University of Liverpool",
        "London School of Economics",
        "London School of Economics and Political Science",
        "LSE",
        "University of Manchester",
        "Newcastle University",
        "University of Nottingham",
        "University of Oxford",
        "Queen Mary University of London",
        "Queen's University Belfast",
        "University of Sheffield",
        "University of Southampton",
        "University College London",
        "UCL",
        "University of Warwick",
        "University of York",

        // Other Major Universities
        "Aston University",
        "University of Bath",
        "Birkbeck, University of London",
        "Bournemouth University",
        "University of Bradford",
        "University of Brighton",
        "Brunel University London",
        "University of Buckingham",
        "Canterbury Christ Church University",
        "City, University of London",
        "Coventry University",
        "Cranfield University",
        "De Montfort University",
        "University of Derby",
        "University of Dundee",
        "University of East Anglia",
        "UEA",
        "University of East London",
        "Edge Hill University",
        "University of Essex",
        "Falmouth University",
        "University of Greenwich",
        "Heriot-Watt University",
        "University of Hertfordshire",
        "University of Huddersfield",
        "University of Hull",
        "Keele University",
        "University of Kent",
        "Kingston University",
        "Lancaster University",
        "University of Leicester",
        "University of Lincoln",
        "Liverpool John Moores University",
        "Liverpool Hope University",
        "University of London",
        "London Metropolitan University",
        "London South Bank University",
        "Loughborough University",
        "Manchester Metropolitan University",
        "Middlesex University",
        "Northumbria University",
        "Norwich University of the Arts",
        "Nottingham Trent University",
        "Open University",
        "The Open University",
        "Oxford Brookes University",
        "University of Plymouth",
        "University of Portsmouth",
        "Queen Margaret University",
        "University of Reading",
        "Robert Gordon University",
        "Roehampton University",
        "Royal Holloway, University of London",
        "Royal Holloway",
        "University of Salford",
        "SOAS University of London",
        "SOAS",
        "Sheffield Hallam University",
        "University of South Wales",
        "University of St Andrews",
        "St Andrews",
        "Staffordshire University",
        "University of Stirling",
        "University of Strathclyde",
        "University of Sunderland",
        "University of Surrey",
        "University of Sussex",
        "Swansea University",
        "Teesside University",
        "Ulster University",
        "University of the West of England",
        "UWE Bristol",
        "University of the West of Scotland",
        "University of Westminster",
        "University of Winchester",
        "University of Wolverhampton",
        "University of Worcester",
        "Wrexham University",
        "York St John University",

        // Post-1992 Universities (former polytechnics)
        "Leeds Beckett University",
        "Birmingham City University",
        "University of Bedfordshire",
        "Anglia Ruskin University",
        "University of Central Lancashire",
        "University of West London",
        "University of Northampton",
        "University of Chichester",
        "Plymouth Marjon University",
        "Bath Spa University",
        "Solent University",
        "University of Bolton",
        "University of Cumbria",
        "University of Chester",
        "University of Gloucestershire",
        "University of Suffolk",
        "Newman University",
        "Bishop Grosseteste University",
        "Harper Adams University",
        "Royal Agricultural University",

        // Scottish Universities
        "University of Aberdeen",
        "Abertay University",
        "Edinburgh Napier University",
        "Glasgow Caledonian University",
        "University of the Highlands and Islands",

        // Welsh Universities
        "Aberystwyth University",
        "Bangor University",
        "University of South Wales",
        "Wrexham Glyndwr University",
        "Wrexham University",
        "Cardiff Metropolitan University",

        // Northern Ireland
        "Ulster University",
        "Queen's University Belfast",

        // Specialist Institutions
        "Royal Academy of Music",
        "Royal College of Art",
        "Royal College of Music",
        "Royal Northern College of Music",
        "Royal Veterinary College",
        "Goldsmiths, University of London",
        "Goldsmiths",
        "Courtauld Institute of Art",
        "London Business School",
        "LBS",
        "Guildhall School of Music and Drama",
        "Trinity Laban Conservatoire of Music and Dance",
        "Arts University Bournemouth",
        "University for the Creative Arts",
        "Ravensbourne University London",

        // Professional Bodies (accredited qualification-awarding)
        "CIPD",
        "Chartered Institute of Personnel and Development",
        "CIMA",
        "Chartered Institute of Management Accountants",
        "ACCA",
        "Association of Chartered Certified Accountants",
        "ICAEW",
        "Institute of Chartered Accountants in England and Wales",
        "ICAS",
        "Institute of Chartered Accountants of Scotland",
        "CII",
        "Chartered Insurance Institute",
        "CIPS",
        "Chartered Institute of Procurement and Supply",
        "CMI",
        "Chartered Management Institute",

        // Business Schools (accredited)
        "Henley Business School",
        "Warwick Business School",
        "Manchester Business School",
        "Said Business School",
        "Judge Business School",
        "Cass Business School",
        "Bayes Business School",
        "Imperial College Business School",
        "Cranfield School of Management",
        "Ashridge Business School",
        "Alliance Manchester Business School",

        // Notable Further Education Colleges
        "Loughborough College",
        "City of Bristol College",
        "Newcastle College",
        "Leeds City College",
        "City College Norwich",
        "Weston College",
        "Chichester College",
        "Hartpury College",
        "Myerscough College",
        "Plumpton College",
        "Writtle University College",
    };

    /// <summary>
    /// Common name variations and abbreviations mapped to official names.
    /// </summary>
    public static readonly Dictionary<string, string> NameVariations = new(StringComparer.OrdinalIgnoreCase)
    {
        ["Cambridge"] = "University of Cambridge",
        ["Oxford"] = "University of Oxford",
        ["Cambridge University"] = "University of Cambridge",
        ["Oxford University"] = "University of Oxford",
        ["Imperial"] = "Imperial College London",
        ["Imperial College"] = "Imperial College London",
        ["Kings College London"] = "King's College London",
        ["Kings London"] = "King's College London",
        ["KCL"] = "King's College London",
        ["Edinburgh"] = "University of Edinburgh",
        ["Manchester"] = "University of Manchester",
        ["Bristol"] = "University of Bristol",
        ["Warwick"] = "University of Warwick",
        ["Durham"] = "Durham University",
        ["Bath"] = "University of Bath",
        ["Exeter"] = "University of Exeter",
        ["York"] = "University of York",
        ["Leeds"] = "University of Leeds",
        ["Sheffield"] = "University of Sheffield",
        ["Birmingham"] = "University of Birmingham",
        ["Nottingham"] = "University of Nottingham",
        ["Southampton"] = "University of Southampton",
        ["Glasgow"] = "University of Glasgow",
        ["Liverpool"] = "University of Liverpool",
        ["Lancaster"] = "Lancaster University",
        ["Leicester"] = "University of Leicester",
        ["Surrey"] = "University of Surrey",
        ["Sussex"] = "University of Sussex",
        ["Reading"] = "University of Reading",
        ["Loughborough"] = "Loughborough University",
        ["Brunel"] = "Brunel University London",
        ["Kent"] = "University of Kent",
        ["Essex"] = "University of Essex",
        ["Strathclyde"] = "University of Strathclyde",
        ["Heriot Watt"] = "Heriot-Watt University",
        ["Heriot-Watt"] = "Heriot-Watt University",
        ["St Andrews University"] = "University of St Andrews",
        ["Saint Andrews"] = "University of St Andrews",
        ["Birkbeck"] = "Birkbeck, University of London",
        ["QMUL"] = "Queen Mary University of London",
        ["Queen Mary"] = "Queen Mary University of London",
        ["Royal Holloway University"] = "Royal Holloway, University of London",
        ["RHUL"] = "Royal Holloway, University of London",
        ["Hull University"] = "University of Hull",
        ["Hull"] = "University of Hull",

        // Additional "X University" variations for "University of X" institutions
        ["Birmingham University"] = "University of Birmingham",
        ["Bristol University"] = "University of Bristol",
        ["Edinburgh University"] = "University of Edinburgh",
        ["Exeter University"] = "University of Exeter",
        ["Glasgow University"] = "University of Glasgow",
        ["Leeds University"] = "University of Leeds",
        ["Leicester University"] = "University of Leicester",
        ["Liverpool University"] = "University of Liverpool",
        ["Manchester University"] = "University of Manchester",
        ["Nottingham University"] = "University of Nottingham",
        ["Sheffield University"] = "University of Sheffield",
        ["Southampton University"] = "University of Southampton",
        ["Warwick University"] = "University of Warwick",
        ["York University"] = "University of York",
        ["Bath University"] = "University of Bath",
        ["Bradford University"] = "University of Bradford",
        ["Brighton University"] = "University of Brighton",
        ["Derby University"] = "University of Derby",
        ["Dundee University"] = "University of Dundee",
        ["Essex University"] = "University of Essex",
        ["Greenwich University"] = "University of Greenwich",
        ["Hertfordshire University"] = "University of Hertfordshire",
        ["Huddersfield University"] = "University of Huddersfield",
        ["Kent University"] = "University of Kent",
        ["Lincoln University"] = "University of Lincoln",
        ["Plymouth University"] = "University of Plymouth",
        ["Portsmouth University"] = "University of Portsmouth",
        ["Reading University"] = "University of Reading",
        ["Salford University"] = "University of Salford",
        ["Surrey University"] = "University of Surrey",
        ["Sussex University"] = "University of Sussex",
        ["Westminster University"] = "University of Westminster",
        ["Winchester University"] = "University of Winchester",
        ["Wolverhampton University"] = "University of Wolverhampton",
        ["Worcester University"] = "University of Worcester",
        ["Aberdeen University"] = "University of Aberdeen",
        ["Stirling University"] = "University of Stirling",
        ["Strathclyde University"] = "University of Strathclyde",
        ["Aberystwyth University"] = "Aberystwyth University",
        ["Bangor University"] = "Bangor University",
        ["Swansea University"] = "Swansea University",

        // London university variations
        ["UCL"] = "University College London",
        ["University College, London"] = "University College London",
        ["East London University"] = "University of East London",
        ["London Metropolitan"] = "London Metropolitan University",
        ["London Met"] = "London Metropolitan University",
        ["South Bank University"] = "London South Bank University",
        ["LSBU"] = "London South Bank University",

        // Historical polytechnic names (became universities in 1992)
        // These are legitimate institutions that existed under different names
        ["South Bank Polytechnic"] = "London South Bank University",
        ["Polytechnic of the South Bank"] = "London South Bank University",
        ["Thames Polytechnic"] = "University of Greenwich",
        ["Woolwich Polytechnic"] = "University of Greenwich",
        ["Polytechnic of Central London"] = "University of Westminster",
        ["PCL"] = "University of Westminster",
        ["Polytechnic of North London"] = "London Metropolitan University",
        ["City of London Polytechnic"] = "London Metropolitan University",
        ["London Guildhall University"] = "London Metropolitan University",
        ["University of North London"] = "London Metropolitan University",
        ["Polytechnic of East London"] = "University of East London",
        ["North East London Polytechnic"] = "University of East London",
        ["Middlesex Polytechnic"] = "Middlesex University",
        ["Hatfield Polytechnic"] = "University of Hertfordshire",
        ["Sheffield Polytechnic"] = "Sheffield Hallam University",
        ["Sheffield City Polytechnic"] = "Sheffield Hallam University",
        ["Manchester Polytechnic"] = "Manchester Metropolitan University",
        ["Leeds Polytechnic"] = "Leeds Beckett University",
        ["Leeds Metropolitan University"] = "Leeds Beckett University",
        ["Leicester Polytechnic"] = "De Montfort University",
        ["Coventry Polytechnic"] = "Coventry University",
        ["Lanchester Polytechnic"] = "Coventry University",
        ["Brighton Polytechnic"] = "University of Brighton",
        ["Portsmouth Polytechnic"] = "University of Portsmouth",
        ["Plymouth Polytechnic"] = "University of Plymouth",
        ["Polytechnic South West"] = "University of Plymouth",
        ["Oxford Polytechnic"] = "Oxford Brookes University",
        ["Newcastle Polytechnic"] = "Northumbria University",
        ["Newcastle upon Tyne Polytechnic"] = "Northumbria University",
        ["Sunderland Polytechnic"] = "University of Sunderland",
        ["Teesside Polytechnic"] = "Teesside University",
        ["Huddersfield Polytechnic"] = "University of Huddersfield",
        ["Wolverhampton Polytechnic"] = "University of Wolverhampton",
        ["Liverpool Polytechnic"] = "Liverpool John Moores University",
        ["Bristol Polytechnic"] = "University of the West of England",
        ["Kingston Polytechnic"] = "Kingston University",
        ["Nottingham Polytechnic"] = "Nottingham Trent University",
        ["Trent Polytechnic"] = "Nottingham Trent University",
        ["Birmingham Polytechnic"] = "Birmingham City University",
        ["City of Birmingham Polytechnic"] = "Birmingham City University",
        ["University of Central England"] = "Birmingham City University",
        ["UCE Birmingham"] = "Birmingham City University",
        ["Staffordshire Polytechnic"] = "Staffordshire University",
        ["North Staffordshire Polytechnic"] = "Staffordshire University",
        ["Luton College of Higher Education"] = "University of Bedfordshire",
        ["University of Luton"] = "University of Bedfordshire",
        ["Anglia Polytechnic"] = "Anglia Ruskin University",
        ["Anglia Polytechnic University"] = "Anglia Ruskin University",
        ["APU"] = "Anglia Ruskin University",
        ["Cambridgeshire College of Arts and Technology"] = "Anglia Ruskin University",
        ["CCAT"] = "Anglia Ruskin University",
        ["Bournemouth Polytechnic"] = "Bournemouth University",
        ["Dorset Institute of Higher Education"] = "Bournemouth University",
        ["Derby College of Higher Education"] = "University of Derby",
        ["Derbyshire College of Higher Education"] = "University of Derby",
        ["Humberside Polytechnic"] = "University of Lincoln",
        ["Humberside College of Higher Education"] = "University of Lincoln",
        ["University of Humberside"] = "University of Lincoln",
        ["University of Lincolnshire and Humberside"] = "University of Lincoln",
        ["Central Lancashire Polytechnic"] = "University of Central Lancashire",
        ["Preston Polytechnic"] = "University of Central Lancashire",
        ["Lancashire Polytechnic"] = "University of Central Lancashire",
        ["Glamorgan Polytechnic"] = "University of South Wales",
        ["Polytechnic of Wales"] = "University of South Wales",
        ["University of Glamorgan"] = "University of South Wales",
        ["Robert Gordon Institute of Technology"] = "Robert Gordon University",
        ["RGIT"] = "Robert Gordon University",
        ["Napier Polytechnic"] = "Edinburgh Napier University",
        ["Napier College"] = "Edinburgh Napier University",
        ["Glasgow Polytechnic"] = "Glasgow Caledonian University",
        ["Queen's College Glasgow"] = "Glasgow Caledonian University",
        ["Dundee Institute of Technology"] = "Abertay University",
        ["Dundee College of Technology"] = "Abertay University",

        // Other historical name changes
        ["Roehampton Institute"] = "Roehampton University",
        ["University of Surrey Roehampton"] = "Roehampton University",
        ["Thames Valley University"] = "University of West London",
        ["Polytechnic of West London"] = "University of West London",
        ["Ealing College of Higher Education"] = "University of West London",
        ["London College of Music and Media"] = "University of West London",
        ["University College Northampton"] = "University of Northampton",
        ["Nene College"] = "University of Northampton",
        ["University College Worcester"] = "University of Worcester",
        ["Worcester College of Higher Education"] = "University of Worcester",
        ["University College Chichester"] = "University of Chichester",
        ["Chichester Institute of Higher Education"] = "University of Chichester",
        ["College of St Mark and St John"] = "Plymouth Marjon University",
        ["Marjon"] = "Plymouth Marjon University",
        ["University of St Mark and St John"] = "Plymouth Marjon University",
        ["University College Falmouth"] = "Falmouth University",
        ["Falmouth College of Arts"] = "Falmouth University",
        ["Bath College of Higher Education"] = "Bath Spa University",
        ["Bath Spa University College"] = "Bath Spa University",
        ["Liverpool Institute of Higher Education"] = "Liverpool Hope University",
        ["Liverpool Hope University College"] = "Liverpool Hope University",
        ["University of Wales, Newport"] = "University of South Wales",
        ["University of Wales Institute, Cardiff"] = "Cardiff Metropolitan University",
        ["UWIC"] = "Cardiff Metropolitan University",
        ["North East Wales Institute"] = "Wrexham University",
        ["NEWI"] = "Wrexham University",
        ["Glyndwr University"] = "Wrexham University",
        ["Wrexham Glyndwr University"] = "Wrexham University",

        // Other common variations
        ["Open University"] = "The Open University",
        ["OU"] = "The Open University",
        ["Northumbria"] = "Northumbria University",
        ["De Montfort"] = "De Montfort University",
        ["DMU"] = "De Montfort University",
        ["Sheffield Hallam"] = "Sheffield Hallam University",
        ["Nottingham Trent"] = "Nottingham Trent University",
        ["NTU"] = "Nottingham Trent University",
        ["Oxford Brookes"] = "Oxford Brookes University",
        ["MMU"] = "Manchester Metropolitan University",
        ["Manchester Met"] = "Manchester Metropolitan University",
        ["Liverpool John Moores"] = "Liverpool John Moores University",
        ["LJMU"] = "Liverpool John Moores University",
        ["UWE"] = "University of the West of England",
        ["West of England"] = "University of the West of England",
    };

    /// <summary>
    /// Check if an institution is recognised. Handles common variations.
    /// </summary>
    public static bool IsRecognised(string institutionName)
    {
        if (string.IsNullOrWhiteSpace(institutionName))
            return false;

        var normalised = institutionName.Trim();

        // Direct match
        if (RecognisedInstitutions.Contains(normalised))
            return true;

        // Check variations
        if (NameVariations.TryGetValue(normalised, out var officialName))
            return RecognisedInstitutions.Contains(officialName);

        // Fuzzy match - check if any recognised institution contains the search term
        // or if the search term contains a recognised institution
        foreach (var institution in RecognisedInstitutions)
        {
            if (institution.Contains(normalised, StringComparison.OrdinalIgnoreCase) ||
                normalised.Contains(institution, StringComparison.OrdinalIgnoreCase))
            {
                return true;
            }
        }

        return false;
    }

    /// <summary>
    /// Get the official name of an institution if found.
    /// </summary>
    public static string? GetOfficialName(string institutionName)
    {
        if (string.IsNullOrWhiteSpace(institutionName))
            return null;

        var normalised = institutionName.Trim();

        // Direct match
        if (RecognisedInstitutions.Contains(normalised))
            return normalised;

        // Check variations
        if (NameVariations.TryGetValue(normalised, out var officialName))
            return officialName;

        // Try automatic "X University" ↔ "University of X" transformation
        var transformed = TryTransformUniversityName(normalised);
        if (transformed != null && RecognisedInstitutions.Contains(transformed))
            return transformed;

        // Handle compound names (e.g., "Loughborough College/Motorsport UK Academy")
        // Split by common separators and check each part
        var separators = new[] { '/', '&', '-', '–', '—', ',' };
        if (normalised.IndexOfAny(separators) >= 0)
        {
            var parts = normalised.Split(separators, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
            foreach (var part in parts)
            {
                // Try direct match on part
                if (RecognisedInstitutions.Contains(part))
                    return part;

                // Try variation match on part
                if (NameVariations.TryGetValue(part, out var partOfficialName))
                    return partOfficialName;

                // Try fuzzy match on part
                foreach (var institution in RecognisedInstitutions)
                {
                    if (institution.Contains(part, StringComparison.OrdinalIgnoreCase) ||
                        part.Contains(institution, StringComparison.OrdinalIgnoreCase))
                    {
                        return institution;
                    }
                }
            }
        }

        // Fuzzy match on full name
        foreach (var institution in RecognisedInstitutions)
        {
            if (institution.Contains(normalised, StringComparison.OrdinalIgnoreCase) ||
                normalised.Contains(institution, StringComparison.OrdinalIgnoreCase))
            {
                return institution;
            }
        }

        return null;
    }

    /// <summary>
    /// Attempts to transform university name between common formats:
    /// "X University" ↔ "University of X"
    /// </summary>
    private static string? TryTransformUniversityName(string name)
    {
        // Try "X University" → "University of X"
        if (name.EndsWith(" University", StringComparison.OrdinalIgnoreCase))
        {
            var place = name[..^11].Trim(); // Remove " University"
            return $"University of {place}";
        }

        // Try "University of X" → "X University"
        if (name.StartsWith("University of ", StringComparison.OrdinalIgnoreCase))
        {
            var place = name[14..].Trim(); // Remove "University of "
            return $"{place} University";
        }

        return null;
    }
}
