"""Scraper for the Supreme Court of Michigan
CourtID: mich
Court Short Name: Mich.
Contact: sitefeedback@courts.mi.gov
History:
    - 2014-09-21: Updated by Jon Andersen to handle some fields being missing
    - 2014-08-05: Updated to have a dynamic URL, an oversight during check in.
    - 2022-01-28: Updated for new web site, @satsuki-chan.
"""
import re
from typing import List
from urllib.parse import urlencode

from juriscraper.lib.string_utils import titlecase
from juriscraper.OpinionSiteLinear import OpinionSiteLinear


class Site(OpinionSiteLinear):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.court_id = self.__module__
        self.filters = (
            ("releaseDate", "Past Year"),
            ("page", "1"),
            ("sortOrder", "Newest"),
            ("searchQuery", ""),
            ("resultType", "opinions"),
            ("pageSize", "100"),
        )
        self.court = "Supreme Court"
        params = self.filters + (
            ("resource", "supreme-court-opinion"),
            ("aAppellateCourt", self.court),
        )
        self.url = f"https://www.courts.michigan.gov/api/CaseSearch/SearchCaseOpinions?{urlencode(params)}"
        # Currently blocked from Michigan so we drop the user agent for now
        self.request["headers"] = {"User-Agent": ""}
        self.title_re = r"(MSC|COA) (?P<docket>\d+)\s+(?P<name>.+)\s+Opinion"
        self.status = "Published"
        self.cases = []

    def _process_html(self) -> None:
        """Process the html and extract out the opinions

        :return: None
        """
        for item in self.html["searchItems"]:
            match = re.search(self.title_re, item["title"])
            if match:
                docket = match.group("docket")
                name = self.cleanup_case_name(match.group("name"))
            else:
                # In some cases the case name is missing. Grab the docket from the title in a different manner
                docket = item["title"].split("_")[0]
                name = ""
            url = (
                f"https://www.courts.michigan.gov{item['documentUrl'].strip()}"
            )
            self.cases.append(
                {
                    "date": item["displayDate"],
                    "docket": docket,
                    "name": name,
                    "url": url,
                    "lower_court": self.get_lower_courts(item["courts"]),
                    "title": item["title"],
                }
            )

    def _get_case_names(self) -> List[str]:
        """Get case names if missing

        In some cases the case name is missing. This method will query for it.

        :return: List of case names
        """
        for case in self.cases:
            if case["name"] != "":
                continue
            if not self.test_mode_enabled:
                self.url = f"https://www.courts.michigan.gov/api/CaseSearch/SearchCaseSearchContent/?searchQuery={case['title']}"
                self.html = self._download()
                case["name"] = self.html["caseDetailResults"]["searchItems"][
                    0
                ]["title"].title()
            else:
                case["name"] = "Test Name"
        return [case["name"] for case in self.cases]

    def cleanup_case_name(self, name_raw: str) -> str:
        """Clean up case name in Michigan

        :param name_raw: Raw title string
        :return: Cleaned name
        """
        name = titlecase(name_raw)
        if "People of Mi " in name:
            name = name.replace("People of Mi ", "People of Michigan ")
        return name

    def get_lower_courts(self, courts: List[str]) -> str:
        """Get the lower courts

        :param courts: Court names as an array
        :return: The lower courts combined into a string
        """
        if courts:
            lower_courts = ", ".join(courts).lstrip(", ")
        else:
            lower_courts = ""
        return titlecase(lower_courts)

@@ -411,16 +411,68 @@
 encode%0A%0A
+from juriscraper.DeferringList import DeferringList%0A
 from jur
@@ -2111,122 +2111,8 @@
  %22%22%0A
-            url = (%0A                f%22https://www.courts.michigan.gov%7Bitem%5B'documentUrl'%5D.strip()%7D%22%0A            )%0A
     
@@ -2304,19 +2304,79 @@
  %22url%22: 
-url
+f%22https://www.courts.michigan.gov%7Bitem%5B'documentUrl'%5D.strip()%7D%22
 ,%0A      
@@ -2590,18 +2590,20 @@
 e names 
+*
 if
+*
  missing
@@ -2668,25 +2668,53 @@
 hod 
-will query for it
+uses a deferred list to the get the case name
 .%0A%0A 
@@ -2756,32 +2756,33 @@
         %22%22%22%0A
+%0A
         
 for case in 
@@ -2769,38 +2769,33 @@
         
-for case in self.
+def fetcher(
 case
-s
+)
 :%0A      
@@ -2843,16 +2843,96 @@
     
-continue
+# Return the name we extracted without using fetcher%0A                return case%5B%22name%22%5D
 %0A   
@@ -2944,15 +2944,13 @@
     
+el
 if 
-not 
 self
@@ -2967,17 +2967,203 @@
 _enabled
-:
+():%0A                # if we're in test mode, return a dummy name%0A                return %22Test Name%22%0A            else:%0A                # Else, query the API and return the name of the case
 %0A       
@@ -3481,109 +3481,91 @@
     
-else:%0A                case%5B%22name%22%5D = %22Test Name%22%0A        return %5Bcase%5B%22name%22%5D for case in self.cases%5D
+return case%5B%22name%22%5D%0A%0A        return DeferringList(seed=self.cases, fetcher=fetcher)
 %0A%0A  

Add deferred list to Mich/Ct App