from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select, WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import (StaleElementReferenceException, 
                                      TimeoutException,
                                      NoSuchElementException)
from datetime import datetime
import time
import os
import logging
from flask import Flask, render_template, request, redirect, url_for, flash
import pandas as pd
class CertificateBot:
    def __init__(self, username, password, excel_data, download_folder):
        self.username = username
        self.password = password
        self.excel_data = excel_data
        # self.required_files_folder = required_files_folder
        self.download_folder = download_folder
        self.driver = None
        self.current_index = 0
        
        
        # self.required_docs = os.path.abspath(required_files_folder)

    def process_all_certificates(self):
        try:
            if not self.excel_data:
                return {"success": False, "message": "No data found in Excel file"}
            
            # Process all certificates
            while self.current_index < len(self.excel_data):
                
                full_login = self.current_index == 0
                result = self._process_certificate(full_login=full_login)
                if not result.get('success'):
                    return result
            
                        
        except Exception as e:
            return {"success": False, "message": f"Error processing certificates: {e}"}
        finally:
            self.close_browser()

    def _process_certificate(self, full_login=False):
        try:
            row = self.excel_data[self.current_index]

            
            if full_login:
                self.start_browser()
                login_result = self.login()
              
            
            fill_result = self.fill_certificate()
            if not fill_result.get('success'):
                return fill_result
            
            self.current_index += 1
            return {"success": True, "message": f"Processed  {row}"}
            
        except Exception as e:
            return {"success": False, "message": f"Error processing certificate: {e}"}

    def start_browser(self):
        options = webdriver.ChromeOptions()
        prefs = {
            "download.default_directory": self.download_folder,
            "download.prompt_for_download": False,
            "download.directory_upgrade": True
        }
        options.add_experimental_option("prefs", prefs)
        options.add_experimental_option("detach", True)
        options.add_argument("--disable-gpu")
        self.driver = webdriver.Chrome(options=options)
        self.driver.maximize_window()

    def login(self):
        try:
            self.driver.get("https://www.icegate.gov.in")
            WebDriverWait(self.driver, 20).until(
                EC.element_to_be_clickable((By.LINK_TEXT, "Login / Sign Up"))).click()
            print("click to login")

            # Wait briefly to ensure the new tab is opened
            time.sleep(2)
            
            # Get all window handles
            tabs = self.driver.window_handles
            
            # Switch to the newest tab (usually the last in the list)
            self.driver.switch_to.window(tabs[-1])
            
            # Now you're in the new tab; continue your automation
            print("Switched to new tab:", self.driver.current_url)

            self.driver.execute_script("window.scrollBy(0, 50);")

            WebDriverWait(self.driver, 20).until(
                EC.presence_of_element_located((By.ID, "icegateId")))
            print("wait for icegateID")
            
            self.driver.find_element(By.ID, "icegateId").send_keys(self.username)
            self.driver.find_element(By.ID, "password").send_keys(self.password)
            
            WebDriverWait(self.driver, 20).until(
                EC.element_to_be_clickable((By.XPATH, "//button[normalize-space()='LOGIN']"))).click()
            original_url = self.driver.current_url

            # Wait until the URL changes (max 5 minutes)
            WebDriverWait(self.driver, 20).until(EC.url_changes(original_url))

            print("change URL")
            
            
            return {"success": True, "message": "Login successful"}
            
        except Exception as e:
            return {"success": False, "message": f"Login failed: {e}"}

 
   
    
  
    
    
    def fill_certificate(self):
        try:
            print(1)
            time.sleep(1)
            row = self.excel_data[self.current_index]
            if self.current_index==0:

                services = self.driver.find_element(By.XPATH, "//h5[normalize-space()='Services']")
                print("services")
                self.driver.execute_script("arguments[0].click();", services)
                print("click on services")
    
                self.driver.execute_script("window.scrollBy(0, 100);")
                time.sleep(1)
    
                
    
                wait = WebDriverWait(self.driver, 10)
    
                # Click the chevron corresponding to the "E-Payment" node
                e_payment_chevron = wait.until(EC.element_to_be_clickable((
                    By.XPATH, "//li[.//div[text()[normalize-space()='E-Payment']]]//mat-icon[contains(text(),'chevron_right')]"
                )))
                e_payment_chevron.click()
                print("click on epayment")
    
                voluntary_challan = self.driver.find_element(By.LINK_TEXT, "Create Voluntary Challan")
                self.driver.execute_script("arguments[0].click();", voluntary_challan)
                print("click on create voluntary challan")
                time.sleep(0.30)
    
                time.sleep(1)
                self.driver.execute_script("window.scrollBy(0, 400);")
                print("Scroll down")
                time.sleep(1)

            else:
                self.driver.refresh()
                time.sleep(2)
                self.driver.execute_script("window.scrollBy(0, -700);")
                print("Scroll down 2")
                time.sleep(2)
    
            
            wait = WebDriverWait(self.driver, 20)

            # -------------------------
            # Step 1: Select "Purpose of Payment"
            # -------------------------
            # purpose_of_payment = row["Purpose of Payment"]  
            purpose_of_payment=row["Purpose of Payment"]
            
            # Click the Purpose of Payment dropdown (ID = mat-select-0)
            purpose_dropdown = wait.until(EC.element_to_be_clickable((By.ID, "mat-select-0")))
            purpose_dropdown.click()
            
            # Select the option by visible text
            purpose_option = wait.until(EC.visibility_of_element_located((
                By.XPATH, f"//mat-option//span[normalize-space()='{purpose_of_payment}']"
            )))
            purpose_option.click()

            document_type=row["Document Type"]
            
            # Click the Document Type dropdown (ID = mat-select-1)
            document_type_dropdown = wait.until(EC.element_to_be_clickable((By.ID, "mat-select-1")))
            document_type_dropdown.click()
            
            # Select the option by visible text
            document_option = wait.until(EC.visibility_of_element_located((
                By.XPATH, f"//mat-option//span[normalize-space()='{document_type}']"
            )))
            document_option.click()
          
            print("Selections completed successfully.")

            time.sleep(1)
            self.driver.execute_script("window.scrollBy(0, 400);")
            print("Scroll down")

            if purpose_of_payment=="Other Fees/Charges":
                discription=row["Discription"]
                self.driver.find_element(By.XPATH, "//textarea[@placeholder='Enter Description']").send_keys(discription)
                print("Purpose of discription")
            
            if document_type=="Letter/Document/Order with DIN(DI)":
                discription=row["Discription"]
                self.driver.find_element(By.XPATH, "//textarea[@placeholder='Enter Description']").send_keys(discription)
                print("Purpose of discription")

            
            document_number=row["Document Number"]
            self.driver.find_element(By.ID, "documentNumber").send_keys(document_number)
            print("Document Number")

           
            date_str = row['Document Date']
            print(date_str)     
            if isinstance(date_str, str):
                date_obj = datetime.strptime(date_str, "%d-%b-%y")
            else:
                date_obj = pd.to_datetime(date_str)
            
            day = date_obj.day
            print(day)
            month = date_obj.strftime("%B")
            print(month)
            year = date_obj.year
            print(year)
            aria_label = f"{month} {day}, {year}"
            print(aria_label)
            
           
            
            
            # 1. Click on the calendar icon to open datepicker
            calendar_icon = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "mat-datepicker-toggle button")))
            calendar_icon.click()
            print("calender click")
            time.sleep(2)
            self.driver.execute_script("window.scrollBy(0,-200);")
            
            # 2. Click on the period button (e.g., "2023" or "2002 – 2025")
            period_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.mat-calendar-period-button")))
            period_button.click()
            print("wait for year")
            
            # Select year
            year_xpath = f"//td[normalize-space()='{year}']"
            wait.until(EC.element_to_be_clickable((By.XPATH, year_xpath))).click()
            
            # Select month
            month_xpath = f"//td[@aria-label='{month} {year}']"
            wait.until(EC.element_to_be_clickable((By.XPATH, month_xpath))).click()
            
            # Select day
            aria_label = f"{month} {day}, {year}"
            day_xpath = f"//td[@aria-label='{aria_label}' and not(@aria-disabled='true')]"
            wait.until(EC.element_to_be_clickable((By.XPATH, day_xpath))).click()
            print("Date selected")
            

            wait = WebDriverWait(self.driver, 15)
            location_input = wait.until(EC.visibility_of_element_located((By.ID, "mat-input-1")))
            print("location code show")
            
            # Type the location prefix (e.g., 'INAJM6')
            location_code=row["Location Code"]
            print(location_code)
            location_input.send_keys(location_code)
            time.sleep(1)

            wait.until(EC.element_to_be_clickable((By.XPATH, "//input[@placeholder='Duty to pay']"))).click()
            # time.sleep(1)

            amount_to_pay=row["Amount to pay"]

            self.driver.find_element(By.XPATH, "//input[@placeholder='Duty to pay']").send_keys(amount_to_pay)
            
            print("Amount to Pay")

            time.sleep(1)
            
            self.driver.execute_script("window.scrollBy(0, 200);")
            time.sleep(1)

            # under_protest = self.driver.find_element(By.XPATH, "(//div[@class='mat-radio-outer-circle'])[2]")   
            # self.driver.execute_script("arguments[0].click();", under_protest)

            if row["Under Protest"].lower()=="no":
                under_protest = self.driver.find_element(By.XPATH, "(//div[@class='mat-radio-outer-circle'])[2]")
                self.driver.execute_script("arguments[0].click();", under_protest)
                print("click on No")
            else:
                under_protest = self.driver.find_element(By.XPATH, "(//div[@class='mat-radio-outer-circle'])[1]")
                self.driver.execute_script("arguments[0].click();", under_protest)
                print("click on Yes")
            time.sleep(1)

            

            preview = self.driver.find_element(By.XPATH, "//span[normalize-space()='Preview']")
            self.driver.execute_script("arguments[0].click();", preview)
            print("click to preview")

            self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

            save_challan = self.driver.find_element(By.XPATH, "//span[normalize-space()='Save Challan']")
            self.driver.execute_script("arguments[0].click();", save_challan)
            print("save challan")
            time.sleep(2)

            confirm_save = self.driver.find_element(By.XPATH, "//button[normalize-space()='Save']")
            self.driver.execute_script("arguments[0].click();", confirm_save)
            print("confirm save challan")
            time.sleep(2)

            ok_click = self.driver.find_element(By.XPATH, "//button[normalize-space()='Ok']")
            self.driver.execute_script("arguments[0].click();", ok_click)
            print("final save")
            time.sleep(2)

            


            
    
            return {"success": True, "message": f"Row {self.current_index + 1} processed successfully"}
        
        except Exception as e:
            return {"success": False, "message": f"Error in fill_certificate: {e}"}

    def close_browser(self):
        if self.driver:
            self.driver.quit()
