# Copyright (c) 2023 MetPy Developers.
# Distributed under the terms of the BSD 3-Clause License.
# SPDX-License-Identifier: BSD-3-Clause

from pathlib import Path
import textwrap

import sphinx.util

from metpy.plots import named_areas

states_provinces = ['ak', 'al', 'ar', 'ca', 'co', 'ct', 'dc', 'de', 'fl', 'ga', 'hi',
                    'ia', 'id', 'il', 'in', 'ks', 'ky', 'la', 'ma', 'md', 'me', 'mi',
                    'mn', 'mo', 'ms', 'mt', 'nc', 'nd', 'ne', 'nh', 'nj', 'nm', 'nv',
                    'ny', 'oh', 'ok', 'or', 'pa', 'ri', 'sc', 'sd', 'tn', 'tx', 'ut',
                    'va', 'vt', 'wi', 'wv', 'wy', 'az', 'wa', 'cn', 'cnlcc', 'ab', 'bc',
                    'mb', 'nb', 'nf', 'ns', 'nt', 'nu', 'on', 'pe', 'qb', 'sa', 'yt', 'us',
                    'uslcc', 'awips', 'whlf', 'chlf', 'centus', 'ehlf', 'mehlf', 'bosfa',
                    'miafa', 'chifa', 'dfwfa', 'slcfa', 'sfofa', 'west', 'cent', 'east',
                    'nwus', 'swus', 'ncus', 'scus', 'neus', 'seus']


def generate_area_file(app):
    """Generate an RST file with nicely formatted views of map areas."""
    sphinx.util.logging.getLogger('make_areas').info('Generating areas file...')

    output = Path(app.srcdir) / 'api' / 'areas.rst'
    with output.open('w') as table:
        header = f"""
            .. (comment): DO NOT EDIT this file.
            .. It is auto-generated by running : {__file__}
            .. Please adjust by making changes there.
            .. It is included in the repository only to aid detection of changes.
            .. _api-areas:

            MetPy Area List
            ===============


            """

        table.write(textwrap.dedent(header))

        for ind, area in enumerate(named_areas):
            extent = named_areas[area].bounds
            longname = named_areas[area].description

            area_header = area + '  -  ' + longname + '\n'
            table.write(area_header)
            table.write('-' * len(area_header) + '\n\n')

            if area in states_provinces:
                code = textwrap.dedent(f"""
                .. plot::
                   :context: reset

                    import matplotlib.pyplot as plt
                    import cartopy.crs as ccrs
                    import cartopy.feature as cfeature
                    from metpy.plots import named_areas

                    proj = named_areas['{area}'].projection

                    plt.figure(figsize=(8, 10))
                    ax = plt.subplot(111, projection=proj)
                    ax.set_extent({extent}, ccrs.PlateCarree())
                    ax.add_feature(cfeature.STATES.with_scale('10m'), edgecolor='grey',
                                linewidth=0.75)
                    ax.add_feature(cfeature.COASTLINE.with_scale('10m'), linewidth=1.1)
                    ax.add_feature(cfeature.BORDERS.with_scale('10m'), edgecolor='black')
                    ax.set_title(f'area={area}          name={named_areas[area].description}')


                """)

            else:
                code = textwrap.dedent(f"""
                .. plot::
                   :context: reset

                    import matplotlib.pyplot as plt
                    import cartopy.crs as ccrs
                    import cartopy.feature as cfeature
                    from metpy.plots import named_areas

                    proj = named_areas['{area}'].projection

                    plt.figure(figsize=(8, 10))
                    ax = plt.subplot(111, projection=proj)
                    ax.set_extent({extent}, ccrs.PlateCarree())
                    ax.add_feature(cfeature.COASTLINE.with_scale('10m'), linewidth=1.1)
                    ax.add_feature(cfeature.BORDERS.with_scale('10m'), edgecolor='black')
                    ax.set_title(f'area={area}          name={named_areas[area].description}')


                """)
            table.write(code)
            if not app.config.metpy_generate_all_areas and ind >= 1:
                break


def setup(app):
    """Set up the make_areas extension with a callback once builders are initialized."""
    app.connect('builder-inited', generate_area_file)

    # Add option to only build a couple areas since all take a while--ONLY FOR DEV
    app.add_config_value('metpy_generate_all_areas', default=True, rebuild='html', types=bool)
