import socket
from datetime import datetime, timezone
from enum import Enum
from typing import Optional

from pydantic import BaseModel, validator

from utils.url_parser import parsed_url


class PRModel(BaseModel):
    title: str
    url: str
    date: Optional[datetime]
    company_name: Optional[str]
    company_url: Optional[str]
    source: str
    text: Optional[str]
    summary: str = ""
    relevant_info: dict = {}
    relevant_PR: bool = True
    processed: bool = False  # True if the PR has been summarized, False otherwise
    created_by: str = socket.gethostname()
    created_date: datetime = datetime.now(timezone.utc)
    modified_by: str = socket.gethostname()
    modified_date: datetime = datetime.now(timezone.utc)
    rss_feed_type: Optional[str] = None

    def update_modified(self, modified_by: str = socket.gethostname()):
        """Update the modified_by and modified_date fields"""
        self.modified_by = modified_by
        self.modified_date = datetime.now(timezone.utc)

    def set_fields(self, **kwargs):
        """Set the fields of the model"""
        for key, value in kwargs.items():
            setattr(self, key, value)

    @validator("company_url")
    def validate_company_url(cls, value):
        """Validate company_url field"""
        return value if value is None or value == "" else parsed_url(value).url

    @validator("date")
    def validate_date(cls, value: datetime):
        """Validate date field"""
        return value if value is not None else datetime.now(timezone.utc)

    def upload_pr_model(self):
        """Return the press release information"""
        pr_entry_dict = self.model_dump()
        pr_entry_dict["date"] = self.date.isoformat()
        pr_entry_dict["created_date"] = self.created_date.isoformat()
        pr_entry_dict["modified_date"] = self.modified_date.isoformat()
        self.table.put_item(Item=pr_entry_dict)


class RSSFeed(Enum):
    prlog = ("https://www.prlog.org/news/ind/financial/rss.xml", {"id": "abd"})
    pressrelease_24_7 = (
        "https://rss.24-7pressrelease.com/rss/business_finance.xml",
        {"id": "main1"},
    )
    globenewswire_public_companies = (
        "https://www.globenewswire.com/RssFeed/orgclass/1/feedTitle/GlobeNewswire%20-%20News%20about%20Public%20Companies",
        {"id": "main-body-container"},
    )
    globenewswire_dividend_reports = (
        "https://www.globenewswire.com/RssFeed/subjectcode/12-Dividend%20Reports%20and%20Estimates/feedTitle/GlobeNewswire%20-%20Dividend%20Reports%20and%20Estimates",
        {"id": "main-body-container"},
    )
    globenewswire_bankruptcy = (
        "https://www.globenewswire.com/RssFeed/subjectcode/5-Bankruptcy/feedTitle/GlobeNewswire%20-%20Bankruptcy",
        {"id": "main-body-container"},
    )
    globenewswire_bond_markets = (
        "https://www.globenewswire.com/RssFeed/subjectcode/6-Bond%20Market%20News/feedTitle/GlobeNewswire%20-%20Bond%20Market%20News",
        {"id": "main-body-container"},
    )
    globenewswire_company_announcement = (
        "https://www.globenewswire.com/RssFeed/subjectcode/9-Company%20Announcement/feedTitle/GlobeNewswire%20-%20Company%20Announcement",
        {"id": "main-body-container"},
    )
    globenewswire_corporate_action = (
        "https://www.globenewswire.com/RssFeed/subjectcode/61-Corporate%20Action/feedTitle/GlobeNewswire%20-%20Corporate%20Action",
        {"id": "main-body-container"},
    )
    globenewswire_press_releases = (
        "https://www.globenewswire.com/RssFeed/subjectcode/72-Press%20Releases/feedTitle/GlobeNewswire%20-%20Press%20Releases",
        {"id": "main-body-container"},
    )
    prnewswire = (
        "https://www.prnewswire.com/rss/news-releases-list.rss",
        {"class": "release-body"},
        "section",
    )
    newswire = (
        "https://www.newswire.com/newsroom/rss/business-finance",
        {"class": "pr-html"},
    )

    def __init__(self, url, attributes=None, tag_name="div"):
        self.url = url
        self.tag_name = tag_name
        self.attributes = attributes
