import json
import logging
import sys
from typing import List, Optional

from dotenv import find_dotenv, load_dotenv
from openai import OpenAI
from pydantic import BaseModel, Field
from rich import print as rprint

import instructor

load_dotenv(find_dotenv())

IMAGE_FILE = "image-file.txt"  # file with all the images to be processed

# Add logger
logging.basicConfig()
logger = logging.getLogger("app")
logger.setLevel("INFO")


class Competitor(BaseModel):
    name: str
    features: Optional[List[str]]


# Define models
class Industry(BaseModel):
    """
    Represents competitors from a specific industry extracted from an image using AI.
    """

    name: str = Field(description="The name of the industry")
    competitor_list: List[Competitor] = Field(
        description="A list of competitors for this industry"
    )


class Competition(BaseModel):
    """
    Represents competitors extracted from an image using AI.

    This class serves as a structured representation of
    competitors and their qualities.
    """

    industry_list: List[Industry] = Field(
        description="A list of industries and their competitors"
    )


# Define clients
client_image = instructor.patch(OpenAI(), mode=instructor.Mode.MD_JSON)


# Define functions
def read_images(image_urls: List[str]) -> Competition:
    """
    Given a list of image URLs, identify the competitors in the images.
    """

    logger.info(f"Identifying competitors in images... {len(image_urls)} images")

    return client_image.chat.completions.create(
        model="gpt-4-vision-preview",
        response_model=Competition,
        max_tokens=2048,
        temperature=0,
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": "Identify competitors and generate key features for each competitor.",
                    },
                    *[
                        {"type": "image_url", "image_url": {"url": url}}
                        for url in image_urls
                    ],
                ],
            }
        ],
    )


def process_and_identify_competitors():
    """
    Main function to process the image list file and identify competitors.
    """

    logger.info("Starting app...")

    try:
        with open(IMAGE_FILE, "r") as file:
            logger.info(f"Reading images from file: {IMAGE_FILE}")
            image_list = file.read().splitlines()
            logger.info(f"{len(image_list)} images read from file: {IMAGE_FILE}")
    except Exception as e:
        logger.error(f"Error reading images from file: {IMAGE_FILE}")
        logger.error(e)
        sys.exit(1)

    competitors = read_images(image_list)

    rprint(f"[green]{len(competitors.industry_list)} industries identified:[/green]")
    for industry in competitors.industry_list:
        rprint(f"[green]{industry.name}[/green]")
        rprint(f"[blue]Features: {industry.competitor_list}[/blue]")

    logger.info("Writing results to file...")

    with open("results.json", "w") as f:
        json.dump(
            {
                "competitors": competitors.model_dump(),
            },
            f,
            indent=4,
        )


if __name__ == "__main__":
    process_and_identify_competitors()

"""
Example output:
{
    "competitors": {
        "industry_list": [
            {
                "name": "Accommodation and Hospitality",
                "competitor_list": [
                    {
                        "name": "craigslist",
                        "features": [
                            "Transactions Offline",
                            "Inexpensive"
                        ]
                    },
                    {
                        "name": "couchsurfing",
                        "features": [
                            "Transactions Offline",
                            "Inexpensive"
                        ]
                    },
                    {
                        "name": "BedandBreakfast.com",
                        "features": [
                            "Transactions Offline",
                            "Inexpensive"
                        ]
                    },
                    {
                        "name": "airbnb",
                        "features": [
                            "Transactions Online",
                            "Inexpensive"
                        ]
                    },
                    {
                        "name": "HOSTELS.com",
                        "features": [
                            "Transactions Online",
                            "Inexpensive"
                        ]
                    },
                    {
                        "name": "VRBO",
                        "features": [
                            "Transactions Offline",
                            "Costly"
                        ]
                    },
                    {
                        "name": "Rentahome",
                        "features": [
                            "Transactions Online",
                            "Costly"
                        ]
                    },
                        {
                        "name": "Orbitz",
                        "features": [
                            "Transactions Online",
                            "Costly"
                        ]
                    },
                    {
                        "name": "Hotels.com",
                        "features": [
                            "Transactions Online",
                            "Costly"
                        ]
                    }
                ]
            },
            {
                "name": "E-commerce Wine Retailers",
                "competitor_list": [
                    {
                        "name": "winesimple",
                        "features": [
                            "Ecommerce Retailers",
                            "True Personalized Selections",
                            "Brand Name Wine",
                            "No Inventory Cost",
                            "Target Mass Market"
                        ]
                    },
                    {
                        "name": "nakedwines.com",
                        "features": [
                            "Ecommerce Retailers",
                            "Target Mass Market"
                        ]
                    },
                    {
                        "name": "Club W",
                        "features": [
                            "Ecommerce Retailers",
                            "Brand Name Wine",
                            "Target Mass Market"
                        ]
                    },
                    {
                        "name": "Tasting Room",
                        "features": [
                            "Ecommerce Retailers",
                            "True Personalized Selections",
                            "Brand Name Wine"
                        ]
                    },
                    {
                        "name": "hellovino",
                        "features": [
                            "Ecommerce Retailers",
                            "True Personalized Selections",
                            "No Inventory Cost",
                            "Target Mass Market"
                        ]
                    }
                ]
            }
        ]
    }
}
"""
