import time
import os
import csv
from playwright.sync_api import sync_playwright


def solve_captcha(captcha_image_path):
    """
    Simulate a CAPTCHA solving process manually as
    current implementation assumes manual entry for simplicity.
    """
    print("Manual CAPTCHA solving required. Please solve the CAPTCHA:")
    solved_captcha = input("Enter the CAPTCHA value displayed in the image: ")
    return solved_captcha


def scrape_patent_data(patent_number):
    """
    Scrape patent data for a single patent number.
    """
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)  # Set `headless=False` to visualize the browser
        page = browser.new_page()

        try:
            # Visit website
            page.goto("https://iprsearch.ipindia.gov.in/PublicSearch/PublicationSearch/Eregister", 
                      wait_until="domcontentloaded", timeout=60000)
            print("Page loaded successfully.")

            # Wait for the search form to load and fill details
            page.wait_for_selector('input[name="PatentNumber"]', timeout=60000)  # Wait up to 60 seconds
            page.fill('input[name="PatentNumber"]', patent_number)

            # Wait for CAPTCHA to load and capture the image
            page.wait_for_selector('#Captcha', timeout=60000)
            captcha_element = page.locator('#Captcha')
            captcha_path = 'captcha.png'
            captcha_element.screenshot(path=captcha_path)
            print("CAPTCHA image saved as captcha.png.")

            # Solve the CAPTCHA (manual input for now)
            captcha_text = solve_captcha(captcha_path)

            # Fill the CAPTCHA and submit
            page.fill('input[name="CaptchaText"]', captcha_text)
            page.click('input[name="submit"]')

            # Wait for the search results to load
            page.wait_for_load_state('networkidle', timeout=60000)  # Wait until network is idle

            # Check for error message in case CAPTCHA/data is incorrect
            error_message_locator = page.locator('.error-message, .alert-danger')
            if error_message_locator.count() > 0:
                print("Error:", error_message_locator.text_content().strip())
                return None

            print("Fetching Patent Data...")

            # Extract key details now, ensuring relevant locators are robust
            legal_status = safe_extract_text(page.locator('tr:has-text("Legal Status :") td:nth-child(2)'))

            # Determine the type of date and get the date value
            expiry_text = page.locator('tr:has-text("Date of Expiry :") td:nth-child(2)')
            renewal_text = page.locator('tr:has-text("Due Date of Next Renewal :") td:nth-child(2)')
            if expiry_text.count() > 0:
                date_type = "Date of Expiry"
                date_value = safe_extract_text(expiry_text)
            else:
                date_type = "Due Date of Next Renewal"
                date_value = safe_extract_text(renewal_text)

            # Extract patent and application numbers
            patent_number_text = safe_extract_text(page.locator('tr:has-text("Patent Number") td:nth-child(3)'), default=patent_number)
            application_number = safe_extract_text(page.locator('tr:has-text("Application Number") td:nth-child(3)'), default="N/A")
            
            grant_title = safe_extract_text(page.locator('tr:has-text("Grant Title") td:nth-child(3), tr:has-text("Grant Title") td[colspan="4"]'))
            patentee_name = safe_extract_text(page.locator('table:has-text("Name of Patentee") tr:nth-child(2) td:nth-child(2)'))
            patentee_type = safe_extract_text(page.locator('table:has-text("Name of Patentee") tr:nth-child(2) td:nth-child(3)'))

            # Extract last valid renewal details
            renewal_table = page.locator('table#renual tbody')
            row_count = renewal_table.locator('tr').count()

            last_renewal_year = "N/A"
            last_renewal_amount = "N/A"
            last_renewal_date = "N/A"

            for i in range(row_count - 1, 0, -1):  # Iterate from the last row
                row = renewal_table.locator('tr').nth(i)
                columns = row.locator('td')

                if columns.count() >= 8:  # Ensure the row has enough columns
                    # Extract year, renewal amount, and renewal date
                    year = safe_extract_text(columns.nth(0)).replace('<sup>th</sup>', 'th')
                    renewal_amount = safe_extract_text(columns.nth(5))  # Column 6: Renewal Amount
                    renewal_date = safe_extract_text(columns.nth(7))  # Column 8: Date of Renewal

                    # Skip rows where the values are "--" or empty
                    if year and "--" not in (year, renewal_amount, renewal_date):
                        last_renewal_year = year
                        last_renewal_amount = renewal_amount
                        last_renewal_date = renewal_date
                        break

            # Output the results
            print(f"Legal Status: {legal_status}")
            print(f"Date Type: {date_type}")
            print(f"Date Value: {date_value}")
            print(f"Patent Number: {patent_number_text}")
            print(f"Application Number: {application_number}")
            print(f"Grant Title: {grant_title}")
            print(f"Name of Patentee: {patentee_name}")
            print(f"Patentee Type: {patentee_type}")
            print(f"Last Renewal Year: {last_renewal_year}")
            print(f"Renewal Amount: {last_renewal_amount}")
            print(f"Date of Renewal: {last_renewal_date}")

            # Return results as a dictionary
            return {
                'Patent Number': patent_number_text,
                'Application Number': application_number,
                'Legal Status': legal_status,
                'Date Type': date_type,
                'Date Value': date_value,
                'Grant Title': grant_title,
                'Patentee Name': patentee_name,
                'Patentee Type': patentee_type,
                'Last Renewal Year': last_renewal_year,
                'Renewal Amount': last_renewal_amount,
                'Date of Renewal': last_renewal_date,
            }

        except Exception as e:
            print("Error during scraping:", e)
            return None

        finally:
            # Clean up the captcha file if it exists
            if os.path.exists(captcha_path):
                os.remove(captcha_path)
            browser.close()


def safe_extract_text(locator, default='N/A'):
    """
    Safely extract text from a locator.
    Returns a default value if extraction fails.
    """
    try:
        return locator.inner_html().strip()  # Use `.inner_html()` to correctly handle HTML content like <sup>
    except Exception:
        return default


def save_to_csv(data, filename):
    """
    Save a dictionary of data to a CSV file.
    """
    if data:
        file_exists = os.path.isfile(filename)
        with open(filename, mode='a', newline='', encoding='utf-8') as file:
            writer = csv.DictWriter(file, fieldnames=data.keys())

            # Write header only if the file doesn't already exist
            if not file_exists:
                writer.writeheader()

            writer.writerow(data)
        print(f"Data saved to {filename}")
    else:
        print("No data to save.")


if __name__ == "__main__":
    # Test for a single patent number
    test_patent_number = "412823"  # Replace with the actual patent number to test
    print(f"Scraping data for Patent Number: {test_patent_number}")
    scraped_data = scrape_patent_data(test_patent_number)

    if scraped_data:
        print("Scraping completed successfully. Saving data to CSV...")
        save_to_csv(scraped_data, "patent_data2.csv")
    else:
        print("Failed to scrape patent details.")    i will not type the captcha in treminal i want to directly typr in the text input