import json
# from utils.logger import ServiceLogger
import logging
from datetime import datetime
from typing import List, Optional

import requests
from pr_parser import PRModel, PRParser
from pydantic import HttpUrl

from configs.config import COMTEX_API_KEY
from utils.dynamo_db import DynamoDB


class ComtexModel(PRModel):
    transmissionID: int
    dateline: Optional[str]
    copyrightline: Optional[str]
    keywords: List[str]
    sourceCode: str
    sourceName: str
    companynames: List[str]
    tickers: List[str]
    exchanges: List[str]
    products: List[str]


class ComtexParser(PRParser):
    def __init__(
        self,
        base_url: str = "https://omnia.comtex.com:6502",
        upload_to_db: bool = True,
        check_db: bool = True,
    ):
        "Initializes the ComtexParser with the base URL of the Comtex API"

        self.upload_to_db = upload_to_db
        self.check_db = check_db

        self.api_key = COMTEX_API_KEY
        self.base_url = base_url
        self.source = "Comtex"
        XCM_logger.log(
            logging.DEBUG,
            "ComtexParser",
            "__init__",
            f"Initialized ComtexParser with base URL: {base_url}",
        )

        self.api_data = self.fetch_data_from_api()
        self.pr_items = self.convert_to_pr_model(self.api_data)

        if upload_to_db:
            self.store_data_in_dynamodb()

    def fetch_data_from_api(
        self, start_time: str = "-1hour", end_time: str = "now", limit: int = 100
    ) -> List[dict]:
        "Fetches data from the Comtex API"
        url = f"{self.base_url}/news/v1/search"
        params = {
            "apiKey": self.api_key,
            "startTime": start_time,
            "endTime": end_time,
            "limit": limit,
        }
        XCM_logger.log(
            logging.INFO,
            "ComtexParser",
            inspect.currentframe().f_code.co_name,
            f"Fetching data from Comtex API: {url}",
        )
        response = requests.get(url, params=params)
        response.raise_for_status()
        data = response.json()
        XCM_logger.log(
            logging.INFO,
            "ComtexParser",
            inspect.currentframe().f_code.co_name,
            f"Fetched {len(data['results'])} entries from Comtex API",
        )
        return data["results"]

    def convert_to_pr_model(self, item: list) -> list[PRModel]:
        "Converts a list of Comtex items to a list of PRModel objects"
        pr_data = []
        for item in self.api_data:
            pr_url = f"Comtex-{item['transmissionID']}"

            if self.check_PR_in_db(pr_url):
                continue

            pr_item = PRModel(
                title=item["headline"],
                url=pr_url,
                date=self.stripe_date(item["sourceTimestamp"]),
                company_name=item["companynames"][0] if item["companynames"] else "",
                company_url=None,
                text=self.fetch_pr_text(item["transmissionID"]),
                source=item["sourceName"],
            )
            pr_item.update_modified()
            pr_data.append(pr_item)

        return pr_data

    def fetch_pr_text(self, transmission_id: int) -> str:
        "Fetches the PR text for a given transmission ID from the Comtex API"
        url = f"{self.base_url}/news/v1/getbody"
        params = {"apiKey": self.api_key, "transmissionID": transmission_id}
        XCM_logger.log(
            logging.DEBUG,
            "ComtexParser",
            "fetch_pr_text",
            f"Fetching PR text for transmission ID: {transmission_id}",
        )
        response = requests.get(url, params=params, timeout=10)
        response.raise_for_status()
        data = response.json()
        if data["resultCount"] > 0:
            return data["results"][0]["body"]
        return ""

    def store_data_in_dynamodb(self, items: Optional[List[PRModel]] = None):
        "Stores the PR data in DynamoDB"
        dynamo_db = DynamoDB()
        table = dynamo_db.press_releases

        if not items:
            items = self.pr_items

        for pr_entry in items:
            pr_entry_dict = pr_entry.model_dump()
            pr_entry_dict["date"] = pr_entry.date.isoformat()
            pr_entry_dict["created_date"] = pr_entry.created_date.isoformat()
            pr_entry_dict["modified_date"] = pr_entry.modified_date.isoformat()
            dynamo_db.upload_to_dynamodb(table, pr_entry_dict)

        XCM_logger.log(
            logging.INFO,
            "PRParser",
            inspect.stack()[1].function,
            f"Stored {len(self.pr_items)} entries in DynamoDB",
        )

    def check_PR_in_db(self, pr_link: str) -> bool:
        "Check if the press release with the given link is already in the database"
        if not self.check_db:
            return False

        dynamo_db = DynamoDB()
        table = dynamo_db.press_releases
        item = dynamo_db.get_item(table, pr_link)
        if item is None:
            return False
        return True

    @staticmethod
    def stripe_date(date: str) -> str:
        "Strip the date string to the correct format"
        # the date will come in the format "2024-07-07 20:43:37.000"
        # we need to get the datetime
        return datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f").isoformat()


# Usage example
if __name__ == "__main__":
    parser = ComtexParser(
        base_url="https://omnia.comtex.com:6502",
        upload_to_db=False,
        check_db=False,
    )
    print(parser.api_data)
