namespace RealCV.Application.Data;

/// <summary>
/// Database of historical UK employers that may no longer exist under their original names.
/// Includes companies that were acquired, merged, dissolved, or renamed.
/// Also includes public sector bodies and internal divisions of larger organisations.
/// </summary>
public static class UKHistoricalEmployers
{
    /// <summary>
    /// Maps historical company names to their current/successor company information.
    /// Key: Historical name (case-insensitive)
    /// Value: HistoricalEmployerInfo with successor details
    /// </summary>
    public static readonly Dictionary<string, HistoricalEmployerInfo> HistoricalCompanies =
        new(StringComparer.OrdinalIgnoreCase)
    {
        // Engineering & Construction
        ["Foster Wheeler"] = new("Wood Group / AMEC Foster Wheeler", "Engineering contractor acquired by AMEC in 2014, now part of Wood Group", "00163609"),
        ["Foster Wheeler Ltd"] = new("Wood Group / AMEC Foster Wheeler", "Engineering contractor acquired by AMEC in 2014, now part of Wood Group", "00163609"),
        ["Foster Wheeler Limited"] = new("Wood Group / AMEC Foster Wheeler", "Engineering contractor acquired by AMEC in 2014, now part of Wood Group", "00163609"),
        ["Foster Wheeler PLC"] = new("Wood Group / AMEC Foster Wheeler", "Engineering contractor acquired by AMEC in 2014, now part of Wood Group", "00163609"),
        ["Sir Alexander Gibb and Partners"] = new("Jacobs Engineering", "Historic engineering consultancy (founded 1922), acquired by Jacobs", null),
        ["Alexander Gibb and Partners"] = new("Jacobs Engineering", "Historic engineering consultancy (founded 1922), acquired by Jacobs", null),
        ["Gibb and Partners"] = new("Jacobs Engineering", "Historic engineering consultancy, acquired by Jacobs", null),
        ["Mott MacDonald"] = new("Mott MacDonald", "Still trading - major engineering consultancy", "01243967"),
        ["Ove Arup"] = new("Arup", "Still trading as Arup", "01312453"),
        ["Arup"] = new("Arup", "Major engineering consultancy", "01312453"),
        ["WS Atkins"] = new("SNC-Lavalin / Atkins", "Acquired by SNC-Lavalin in 2017", "01885586"),
        ["Atkins"] = new("SNC-Lavalin / Atkins", "Acquired by SNC-Lavalin in 2017", "01885586"),

        // Pharmaceuticals
        ["Glaxo"] = new("GlaxoSmithKline (GSK)", "Merged with SmithKline Beecham in 2000 to form GSK", "03888792"),
        ["Glaxo Research & Development"] = new("GlaxoSmithKline (GSK)", "Glaxo R&D subsidiary, merged into GSK in 2000", "03888792"),
        ["Glaxo Research & Development Ltd"] = new("GlaxoSmithKline (GSK)", "Glaxo R&D subsidiary, merged into GSK in 2000", "03888792"),
        ["Glaxo Research and Development"] = new("GlaxoSmithKline (GSK)", "Glaxo R&D subsidiary, merged into GSK in 2000", "03888792"),
        ["Glaxo Wellcome"] = new("GlaxoSmithKline (GSK)", "Formed 1995 (Glaxo + Wellcome), merged with SmithKline Beecham 2000", "03888792"),
        ["SmithKline Beecham"] = new("GlaxoSmithKline (GSK)", "Merged with Glaxo Wellcome in 2000 to form GSK", "03888792"),
        ["Beecham"] = new("GlaxoSmithKline (GSK)", "Merged to form SmithKline Beecham, then GSK", "03888792"),
        ["Wellcome"] = new("GlaxoSmithKline (GSK)", "Acquired by Glaxo in 1995", "03888792"),
        ["ICI Pharmaceuticals"] = new("AstraZeneca", "ICI pharma division became Zeneca, merged with Astra 1999", "02723534"),
        ["Zeneca"] = new("AstraZeneca", "Merged with Astra in 1999", "02723534"),

        // Banking & Finance (historical names)
        ["Midland Bank"] = new("HSBC UK", "Acquired by HSBC in 1992", "00014259"),
        ["National Westminster Bank"] = new("NatWest (RBS Group)", "Acquired by RBS in 2000", "00929027"),
        ["NatWest"] = new("NatWest Group", "Part of NatWest Group (formerly RBS)", "00929027"),
        ["Lloyds Bank"] = new("Lloyds Banking Group", "Part of Lloyds Banking Group", "00002065"),
        ["Lloyds TSB"] = new("Lloyds Banking Group", "Rebranded to Lloyds Bank in 2013", "00002065"),
        ["TSB"] = new("TSB Bank", "Demerged from Lloyds in 2013, acquired by Sabadell", "SC205310"),
        ["Halifax"] = new("Halifax (Lloyds Banking Group)", "Part of Lloyds Banking Group since 2009", "02367076"),
        ["HBOS"] = new("Lloyds Banking Group", "Acquired by Lloyds in 2009", "SC218813"),
        ["Bank of Scotland"] = new("Bank of Scotland (Lloyds Banking Group)", "Part of Lloyds Banking Group", "SC327000"),
        ["Abbey National"] = new("Santander UK", "Acquired by Santander in 2004", "02294747"),
        ["Alliance & Leicester"] = new("Santander UK", "Acquired by Santander in 2008", "03263713"),
        ["Bradford & Bingley"] = new("Santander UK (savings) / UKAR (mortgages)", "Nationalised 2008, split up", "00189520"),
        ["Northern Rock"] = new("Virgin Money UK", "Nationalised 2008, sold to Virgin Money 2012", "03273685"),

        // Retail
        ["Woolworths"] = new("Dissolved", "UK Woolworths went into administration in 2008", "00106966"),
        ["British Home Stores"] = new("Dissolved", "BHS went into administration in 2016", "00229606"),
        ["BHS"] = new("Dissolved", "BHS went into administration in 2016", "00229606"),
        ["Littlewoods"] = new("Shop Direct / The Very Group", "Stores closed, online business continued", null),
        ["Comet"] = new("Dissolved", "Electrical retailer went into administration in 2012", "00abortedte"),
        ["MFI"] = new("Dissolved", "Furniture retailer went into administration in 2008", null),
        ["Courts"] = new("Dissolved", "Furniture retailer ceased UK operations", null),
        ["Safeway"] = new("Morrisons", "UK stores acquired by Morrisons in 2004", "00358949"),
        ["Kwik Save"] = new("Dissolved", "Supermarket chain dissolved in 2007", null),
        ["Fine Fare"] = new("Dissolved", "Supermarket chain - stores sold to various buyers", null),
        ["Gateway"] = new("Somerfield / Co-op", "Became Somerfield, then acquired by Co-op", null),
        ["Somerfield"] = new("Co-operative Group", "Acquired by Co-op in 2009", null),

        // Telecoms
        ["British Telecom"] = new("BT Group", "Rebranded to BT", "01800000"),
        ["GPO Telephones"] = new("BT Group", "Became British Telecom, then BT", "01800000"),
        ["Mercury Communications"] = new("Cable & Wireless / Vodafone", "Merged into Cable & Wireless, later Vodafone", null),
        ["Cellnet"] = new("O2 (Virgin Media O2)", "Became BT Cellnet, then O2", null),
        ["Orange"] = new("EE (BT)", "Merged with T-Mobile to form EE, acquired by BT", null),
        ["T-Mobile UK"] = new("EE (BT)", "Merged with Orange to form EE", null),
        ["One2One"] = new("EE (BT)", "Became T-Mobile UK, then EE", null),

        // Utilities
        ["Central Electricity Generating Board"] = new("National Grid / Various generators", "CEGB privatised and split in 1990", null),
        ["CEGB"] = new("National Grid / Various generators", "CEGB privatised and split in 1990", null),
        ["British Gas"] = new("Centrica / National Grid", "Demerged in 1997", "00029782"),
        ["Eastern Electricity"] = new("EDF Energy", "Privatised, now part of EDF", null),
        ["London Electricity"] = new("EDF Energy", "Privatised, now part of EDF", null),
        ["SEEBOARD"] = new("EDF Energy", "Privatised, now part of EDF", null),
        ["PowerGen"] = new("E.ON UK", "Acquired by E.ON", null),
        ["National Power"] = new("RWE npower / Innogy", "Split and acquired", null),

        // Manufacturing & Industrial
        ["British Steel"] = new("Tata Steel UK / British Steel (2016)", "Privatised, acquired by Corus then Tata, British Steel name revived 2016", "12303256"),
        ["British Steel Corporation"] = new("Tata Steel UK / British Steel (2016)", "Nationalised steel industry, privatised 1988", "12303256"),
        ["British Steel plc"] = new("Tata Steel UK / British Steel (2016)", "Merged with Hoogovens to form Corus 1999", "12303256"),
        ["Corus"] = new("Tata Steel UK", "Acquired by Tata Steel in 2007", null),
        ["British Leyland"] = new("Various (BMW, Tata, etc.)", "Split up - brands went to various owners", null),
        ["Rover Group"] = new("Dissolved", "Final owner MG Rover went bankrupt 2005", null),
        ["MG Rover"] = new("Dissolved", "Went into administration in 2005", null),
        ["Austin Rover"] = new("Dissolved", "Part of British Leyland, became Rover Group", null),
        ["British Aerospace"] = new("BAE Systems", "Merged with Marconi Electronic Systems in 1999", "01470151"),
        ["BAe"] = new("BAE Systems", "Merged with Marconi Electronic Systems in 1999", "01470151"),
        ["Marconi"] = new("BAE Systems / Ericsson", "Defence division to BAE, telecoms to Ericsson", null),
        ["GEC"] = new("Various", "General Electric Company (UK) - broken up", null),
        ["GEC Marconi"] = new("BAE Systems", "Defence business became part of BAE Systems", "01470151"),
        ["Plessey"] = new("Siemens / various", "Broken up in 1989", null),
        ["ICL"] = new("Fujitsu", "Acquired by Fujitsu", null),
        ["International Computers Limited"] = new("Fujitsu", "Acquired by Fujitsu in 2002", null),
        ["Ferranti"] = new("Dissolved", "Collapsed in 1993 after fraud scandal", null),

        // Oil & Gas
        ["British Petroleum"] = new("BP", "Rebranded to BP", "00102498"),
        ["BP Amoco"] = new("BP", "Merged 1998, rebranded to just BP", "00102498"),
        ["Enterprise Oil"] = new("Shell", "Acquired by Shell in 2002", null),
        ["Lasmo"] = new("Eni", "Acquired by Eni in 2001", null),
        ["Britoil"] = new("BP", "Acquired by BP in 1988", null),

        // Transport
        ["British Rail"] = new("Various (Network Rail, TOCs)", "Privatised and split in 1990s", null),
        ["British Railways"] = new("Various (Network Rail, TOCs)", "Became British Rail, then privatised", null),
        ["Railtrack"] = new("Network Rail", "Replaced by Network Rail in 2002", "04402220"),
        ["British Airways"] = new("British Airways (IAG)", "Now part of International Airlines Group", "01777777"),
        ["British Caledonian"] = new("British Airways", "Acquired by BA in 1987", null),
        ["British European Airways"] = new("British Airways", "Merged with BOAC to form BA in 1974", null),
        ["BEA"] = new("British Airways", "Merged with BOAC to form BA in 1974", null),
        ["BOAC"] = new("British Airways", "Merged with BEA to form BA in 1974", null),
        ["British Overseas Airways Corporation"] = new("British Airways", "Merged with BEA to form BA in 1974", null),
        ["Dan-Air"] = new("British Airways", "Acquired by BA in 1992", null),

        // Media
        ["Thames Television"] = new("Fremantle", "Lost franchise 1991, production continued", null),
        ["Granada Television"] = new("ITV plc", "Merged to form ITV plc", "04967001"),
        ["Carlton Television"] = new("ITV plc", "Merged with Granada to form ITV", "04967001"),
        ["Yorkshire Television"] = new("ITV plc", "Part of ITV plc", "04967001"),
        ["Tyne Tees Television"] = new("ITV plc", "Part of ITV plc", "04967001"),
        ["Central Television"] = new("ITV plc", "Part of ITV plc", "04967001"),
        ["Anglia Television"] = new("ITV plc", "Part of ITV plc", "04967001"),
        ["HTV"] = new("ITV plc", "Part of ITV plc", "04967001"),
        ["LWT"] = new("ITV plc", "London Weekend Television, part of ITV", "04967001"),
        ["London Weekend Television"] = new("ITV plc", "Part of ITV plc", "04967001"),

        // Construction
        ["Wimpey"] = new("Taylor Wimpey", "Merged with Taylor Woodrow in 2007", "00296805"),
        ["Taylor Woodrow"] = new("Taylor Wimpey", "Merged with Wimpey in 2007", "00296805"),
        ["John Laing"] = new("John Laing Group (infrastructure)", "Construction sold, now infrastructure investor", "05975300"),
        ["Costain Group"] = new("Costain", "Still trading", "00102921"),
        ["Tarmac"] = new("Tarmac (CRH)", "Construction now part of CRH", null),
        ["Alfred McAlpine"] = new("Carillion (dissolved)", "Acquired by Carillion, which collapsed 2018", null),
        ["Carillion"] = new("Dissolved", "Collapsed into liquidation in 2018", "03782379"),
        ["Mowlem"] = new("Carillion (dissolved)", "Acquired by Carillion in 2006", null),
        ["Balfour Beatty"] = new("Balfour Beatty", "Still trading", "00395826"),

        // Insurance
        ["Royal Insurance"] = new("RSA Insurance Group", "Merged with Sun Alliance", "02339826"),
        ["Sun Alliance"] = new("RSA Insurance Group", "Merged with Royal Insurance", "02339826"),
        ["Guardian Royal Exchange"] = new("AXA", "Acquired by AXA in 1999", null),
        ["Commercial Union"] = new("Aviva", "Merged to form CGU, then Aviva", "02468686"),
        ["General Accident"] = new("Aviva", "Merged to form CGU, then Aviva", "02468686"),
        ["CGU"] = new("Aviva", "Rebranded to Aviva in 2002", "02468686"),
        ["Norwich Union"] = new("Aviva", "Rebranded to Aviva in 2009", "02468686"),
        ["Eagle Star"] = new("Zurich", "Acquired by Zurich", null),
        ["Prudential"] = new("Prudential plc / M&G", "UK business demerged as M&G plc", "01397169"),
    };

    /// <summary>
    /// Major UK charities and non-profit organisations.
    /// These are legitimate employers but may not be found via standard company search.
    /// </summary>
    public static readonly HashSet<string> CharityEmployers = new(StringComparer.OrdinalIgnoreCase)
    {
        // Youth organisations
        "Girlguiding",
        "Girlguiding UK",
        "Girlguiding North East England",
        "Girl Guides",
        "Scouts",
        "Scout Association",
        "Boys Brigade",
        "Girls Brigade",
        "Cadets",
        "Sea Cadets",
        "Air Cadets",
        "Army Cadets",

        // Major charities
        "British Red Cross",
        "Oxfam",
        "Save the Children",
        "NSPCC",
        "Barnardo's",
        "RSPCA",
        "RSPB",
        "National Trust",
        "Cancer Research UK",
        "British Heart Foundation",
        "Macmillan Cancer Support",
        "Marie Curie",
        "Age UK",
        "Mind",
        "Samaritans",
        "Shelter",
        "Citizens Advice",
        "Citizens Advice Bureau",
        "CAB",
        "St John Ambulance",
        "Salvation Army",
        "YMCA",
        "YWCA",

        // Religious organisations
        "Church of England",
        "Catholic Church",
        "Methodist Church",
        "Baptist Church",
        "Salvation Army",
    };

    /// <summary>
    /// Public sector organisations and government bodies.
    /// These are legitimate employers but not registered at Companies House.
    /// </summary>
    public static readonly HashSet<string> PublicSectorEmployers = new(StringComparer.OrdinalIgnoreCase)
    {
        // Emergency Services
        "Metropolitan Police",
        "Metropolitan Police Service",
        "Metropolitan Police Engineers",
        "Met Police",
        "City of London Police",
        "British Transport Police",
        "Police Scotland",
        "Police Service of Northern Ireland",
        "PSNI",
        "London Fire Brigade",
        "London Ambulance Service",
        "NHS",
        "National Health Service",

        // Government Departments
        "HM Treasury",
        "Home Office",
        "Foreign Office",
        "Ministry of Defence",
        "MOD",
        "Department of Health",
        "Department for Education",
        "DfE",
        "Department for Work and Pensions",
        "DWP",
        "HMRC",
        "HM Revenue and Customs",
        "Cabinet Office",
        "DVLA",
        "DVSA",
        "Environment Agency",
        "Highways Agency",
        "Highways England",
        "National Highways",

        // Armed Forces
        "British Army",
        "Royal Navy",
        "Royal Air Force",
        "RAF",
        "Royal Marines",

        // Local Government
        "London Borough",
        "County Council",
        "City Council",
        "District Council",
        "Metropolitan Borough",
        "Borough Council",
        "Town Council",
        "Parish Council",
        "Greater London Council",
        "GLC",

        // Education
        "University of",
        "College of",
        "School of",

        // Other Public Bodies
        "BBC",
        "British Broadcasting Corporation",
        "Channel 4",
        "Bank of England",
        "Royal Mail",
        "Post Office",
        "Transport for London",
        "TfL",
        "Network Rail",
        "Ordnance Survey",
        "Land Registry",
        "Companies House",
        "National Archives",
        "British Library",
        "British Museum",
        "National Gallery",
        "Tate",
        "Natural History Museum",
        "Science Museum",
        "V&A",
        "Victoria and Albert Museum",
    };

    /// <summary>
    /// Patterns that indicate an internal division or department of a larger company.
    /// These are legitimate employer references but won't be separately registered.
    /// </summary>
    public static readonly Dictionary<string, string> DivisionPatterns = new(StringComparer.OrdinalIgnoreCase)
    {
        // Airlines
        ["British Airways Technical Support"] = "British Airways",
        ["BA Technical Support"] = "British Airways",
        ["BA Engineering"] = "British Airways",
        ["British Airways Engineering"] = "British Airways",
        ["FBA - British Airways"] = "British Airways",

        // Major employers with divisions
        ["BBC News"] = "BBC",
        ["BBC World Service"] = "BBC",
        ["BBC Studios"] = "BBC",
        ["ITV News"] = "ITV plc",
        ["Sky News"] = "Sky UK",
        ["BT Openreach"] = "BT Group",
        ["Openreach"] = "BT Group",
        ["BT Research"] = "BT Group",
        ["Shell Research"] = "Shell",
        ["BP Research"] = "BP",
        ["Rolls-Royce Aerospace"] = "Rolls-Royce",
        ["Rolls-Royce Marine"] = "Rolls-Royce",
        ["BAE Systems Naval Ships"] = "BAE Systems",
        ["BAE Systems Submarines"] = "BAE Systems",

        // Banks - divisions
        ["Barclays Investment Bank"] = "Barclays",
        ["Barclays Capital"] = "Barclays",
        ["HSBC Investment Bank"] = "HSBC",
        ["Lloyds Commercial Banking"] = "Lloyds Banking Group",
        ["NatWest Markets"] = "NatWest Group",
        ["RBS Markets"] = "NatWest Group",
    };

    /// <summary>
    /// Check if an employer name is a known historical company.
    /// </summary>
    public static bool IsHistoricalEmployer(string employerName)
    {
        if (string.IsNullOrWhiteSpace(employerName))
            return false;

        return HistoricalCompanies.ContainsKey(employerName.Trim());
    }

    /// <summary>
    /// Get information about a historical employer.
    /// </summary>
    public static HistoricalEmployerInfo? GetHistoricalEmployerInfo(string employerName)
    {
        if (string.IsNullOrWhiteSpace(employerName))
            return null;

        return HistoricalCompanies.GetValueOrDefault(employerName.Trim());
    }

    /// <summary>
    /// Check if an employer is a public sector organisation.
    /// </summary>
    public static bool IsPublicSectorEmployer(string employerName)
    {
        if (string.IsNullOrWhiteSpace(employerName))
            return false;

        var name = employerName.Trim();

        // Direct match
        if (PublicSectorEmployers.Contains(name))
            return true;

        // Partial match for patterns like "London Borough of X"
        foreach (var pattern in PublicSectorEmployers)
        {
            if (name.Contains(pattern, StringComparison.OrdinalIgnoreCase))
                return true;
        }

        return false;
    }

    /// <summary>
    /// Check if an employer is a charity or non-profit organisation.
    /// </summary>
    public static bool IsCharityEmployer(string employerName)
    {
        if (string.IsNullOrWhiteSpace(employerName))
            return false;

        var name = employerName.Trim();

        // Direct match
        if (CharityEmployers.Contains(name))
            return true;

        // Partial match
        foreach (var pattern in CharityEmployers)
        {
            if (name.Contains(pattern, StringComparison.OrdinalIgnoreCase))
                return true;
        }

        return false;
    }

    /// <summary>
    /// Check if an employer name is an internal division and get the parent company.
    /// </summary>
    public static string? GetParentCompanyForDivision(string employerName)
    {
        if (string.IsNullOrWhiteSpace(employerName))
            return null;

        var name = employerName.Trim();

        // Direct match
        if (DivisionPatterns.TryGetValue(name, out var parent))
            return parent;

        // Partial match
        foreach (var (pattern, parentCompany) in DivisionPatterns)
        {
            if (name.Contains(pattern, StringComparison.OrdinalIgnoreCase))
                return parentCompany;
        }

        return null;
    }
}

/// <summary>
/// Information about a historical employer.
/// </summary>
public sealed record HistoricalEmployerInfo(
    string SuccessorName,
    string Notes,
    string? CompanyNumber
);
