import io

import json

import cv2

import requests

from google import genai

import os

from datetime import datetime

from flask import Flask, render_template, request, redirect, url_for,jsonify  # Ensure redirect and url_for are imported

import shutil  # Add this import at the top of your file

from flask_cors import CORS

from PIL import Image

import re



app = Flask(__name__)



# CORS configuration

CORS(app)  # Enable CORS for all routes



BASE_URL = "https://jmn.sit.sigmentechnologies.com"



# Store page1 data temporarily

TEMP_STORE = {}



#client = genai.Client(api_key="AIzaSyDVF5_plpZvdjsf5WbIX6TSPOt2Sps8hVc")

#client = genai.Client(api_key="AIzaSyAvEn1aSat6yimDMhUHSW15aKBGeXc2zE8")





def parse_gemini_json(text):

    try:

        # Remove markdown like ```json ```

        text = re.sub(r"```json|```", "", text).strip()



        # Extract only JSON part (safer regex)

        match = re.search(r"\{[\s\S]*\}", text)

        if match:

            clean_json = match.group(0)

            return json.loads(clean_json)

        else:

            print("No JSON found in Gemini response")

            return {}



    except Exception as e:

        print("Invalid JSON from Gemini:", str(e))

        return {}



def extract_text_with_gemini(image_path):

    try:

        print(f"Processing file: {image_path}")



        # Read image as bytes

        with open(image_path, "rb") as f:

            image_bytes = f.read()



        response = client.models.generate_content(

            model="gemini-2.5-flash",

            contents=[

                {

                    "role": "user",

                    "parts": [

                        {"text": """Extract all fields from the form and return STRICT JSON.



Format:

{

  "formStart": {

    "form_no": "MUST EXTRACT OR LEAVE EMPTY STRING"

  },

  "studentDetails": {

    "student_name": "",

    "student_dob": "",

    "student_place_of_dob": "",

    "student_nationality": "",

    "student_contact_no": "",

    "student_marital": "",

    "student_religion": "",

    "student_cast": "",

    "student_gender": "",

    "student_mothertongue": "",

    "student_email": "",

    "student_blood_group": ""

  },

  "permenent": {

    "permenent_address": "",

    "permenent_post_office": "",

    "permenent_police_station": "",

    "permenent_district": "",

    "permenent_state": "",

    "permenent_pincode": ""

  },

  "present": {

    "present_address": "",

    "present_post_office": "",

    "present_police_station": "",

    "present_district": "",

    "present_state": "",

    "present_pincode": ""

  },

  "parentDetails": {

    "father_name": "",

    "father_occupation": "",

    "father_mobile_no": "",

    "father_email_id": "",

    "mother_name": "",

    "mother_occupation": "",

    "mother_mobile_no": "",

    "mother_email_id": ""

  }

}



Rules:

- Return ONLY valid JSON

- Do NOT include ```json or ```

- Do NOT include explanation

- Ensure valid JSON (double quotes, no trailing commas)

- Fill all fields from the form

"""},

                        {

                            "inline_data": {

                                "mime_type": "image/jpeg",

                                "data": image_bytes

                            }

                        }

                    ]

                }

            ]

        )

        print("RAW GEMINI RESPONSE:\n", response.text)  

        return response.text



    except Exception as e:

        print("Gemini Error:", str(e))

        return None



    

def extract_text_with_back_gemini(image_path):

    try:

        print(f"Processing file: {image_path}")



        # Read image as bytes

        with open(image_path, "rb") as f:

            image_bytes = f.read()



        response = client.models.generate_content(

            model="gemini-2.5-flash-lite",

            contents=[

                {
                    "role": "user",

                    "parts": [

                        {"text": """Extract all fields from the form and return STRICT JSON.



Format:

{

  "formStart": {

    "form_no": "MUST EXTRACT OR LEAVE EMPTY STRING"

  },

  "localGuardian": {

    "guardian_name": "",

    "guardian_relationship": "",

    "guardian_mobile": "",

    "guardian_email": "",

    "guardian_occupation": "",

    "guardian_address": "",

    "guardian_post_office": "",

    "guardian_police_station": "",

    "guardian_district": "",

    "guardian_state": "",

    "guardian_pincode": ""

  },

  "qualification": {

    "application_date": "",

    "accademic_session": "",

    "programme_study": "",

    "seat_allotment": ""

  },

  "netug": {

    "neet_application_no": "",

    "neet_roll_no": "",

    "neet_percentile": "",

    "neet_total_marks": "",

    "neet_rank": "",

    "neet_category": "",

    "neet_quota": ""

  },

  "x": {

    "board_0": "",

    "cgpa_0": "",

    "year_of_pass_0": ""

  },

  "xii": {

    "board_1": "",

    "cgpa_1": "",

    "year_of_pass_1": ""

  },

  "physics": {

    "marks_0": "",

    "percentage_0": "",

    "total_marks_0": ""

  },

  "chemistry": {

    "marks_1": "",

    "percentage_1": "",

    "total_marks_1": ""

  },

  "biology": {

    "marks_2": "",

    "percentage_2": "",

    "total_marks_2": ""

  },

  "declaration": {

    "submission_date": ""

  }

}



    Rules:

    - Only JSON

    - No explanation

    - Fill all fields from the form

    """},

                        {

                            "inline_data": {

                                "mime_type": "image/jpeg",

                                "data": image_bytes

                            }

                        }

                    ]

                }

            ]

        )

        print("2")

        print("RAW GEMINI RESPONSE:\n", response.text)

        return response.text



    except Exception as e:

        print("Gemini Error:", str(e))

        return None



def extract_text_from_image(image_path):

    try:

        img = cv2.imread(image_path)

        file_bytes = io.BytesIO(cv2.imencode(".jpg", img)[1])

        url_api = "https://api.ocr.space/parse/image"

        result = requests.post(

            url_api,

            files={"image.jpg": file_bytes},

            data={

                "apikey": "K83686776688957",

                "language": "eng",

                "isOverlayRequired": True,

                "detectOrientation": True,

                "scale": True,

                "isTable": True,

                "OCREngine": 2

            }

        )



        result = result.content.decode()

        result = json.loads(result)

        parsed_results = result.get("ParsedResults")

        if parsed_results:

            text_detected = parsed_results[0].get("ParsedText")

        else:

            text_detected = ""

        return text_detected

    except Exception as e:

        print(f"OCR extraction failed: {e}")

        return ""



def replace_text(text):

    try:

        replacements = [

            "REG. OFFICE: A2/15, KALYANI, DIST: NADIA,", "REG. OFFICE: A2/15, KALYANI, DIST.: NADIA,", "ALL FOR EDUCATION, FUCATION FOR ALF", "PIN 741235, WEST BENGAL, INDIA", "RESPECTED SIR/MADAM,", "FURNISHED BELOW FOR YOUR KIND CONSIDERATION.", "MBBS COURSE IN SESSION:", "PARTICULARS ARE",

            "MAIL ID: INFO.JMNEDUR@GMAIL.COM", "CONTACT NO: +91 9831111817",

            "CAMPUS: UTTAR PANCHPOTA, P.O & P. S. CHAKDAHA,", "DIST. NADIPIP INSTALLA, PIN 741222, WEST BENGAL, INDIA",

            "DIST. NADIA, PIN 741222, WEST BENGAL, INDIA", "JMN", "ADMISSION FORM", "THE PRINCIPAL,", "JMN MEDICAL COLLEGE,",

            "UTTAR PANCHPOTA, P.O. & P.S. CHAKDAHA,", "DIST. NADIA, PINCODE - 741222,",

            "WEST BENGAL, INDIA.", "PASTE RECENT", "PASSPORT-SIZE", "COLOUR",

            "PHOTOGRAPH OF", "THE CANDIDATE", "AND SIGN ACROSS", "THE PHOTOGRAPH.",

            "RESPECTED SIR / MADAM,", "I HEREBY APPLY FOR ADMISSION TO THE MBBS COURSE IN SESSION",

            "PARTICULARS ARE FURNISHED BELOW FOR YOUR KIND CONSIDERATION.", "KINDLY USE CAPITAL LETTERS ONLY",

            "STUDENT DETAILS:", "PARENT DETAILS:", "JMN MEDICAL COLLEGE",

            "WWW.JMNMEDICALCOLLEGE.ORG.IN",

            "DATE OF BIRTH:", "PLACE OF BIRTH:", "NATIONALITY:", "CONTACT NO:",

            "MARITAL STATUS:", "RELIGION:", "CASTE:", "GENDER:", "MOTHERTOUNGE:",

            "PERMANENT ADDRESS:", "P.O.:", "PO.:", "P.S.:",

            "DISTRICT:", "STATE:", "PINCODE:", "FATHER'S NAME:", "OCCUPATION:", "_ OCCUPATION:",

            "EMAIL-ID: _", "EMAIL-ID:", "EMAILID:_", "EMAILID:", "EMAIL ID:", "MOTHER'S NAME:", "APPLICATION DATE:",

            "REG. NO.:", "REG. DATE:", "BLOOD GROUP:", "DATE OF BIRTH:",

            "PLACE OF BIRTH:", "MOBILE NO.:", "MOBILE NO:", "MOBILE NO. :", "NATIONALITY:", "PRESENT ADDRESS:",

            "OCCUPATION", "AT THIS COLLEGE. NECESSARY",

            "SEAT ALLOTMENT NO.:", "ACADEMIC SESSION:", "ACADEMIC SESSION: _", "PROGRAMME OF STUDY:", "•",

            "QUALIFICATION DETAILS:", "RELATIONSHIP WITH STUDENT:", "HOUSE NUMBER:", "BLOCK:", "STREET", "VILLAGE OR TOWN:", "ADDRESS DETAILS (PERMANENT ADDRESS):", "ADDRESS DETAILS (PRESENT ADDRESS):", "LOCAL GUARDIAN DETAILS: (IN CASE OF OUTSTATION STUDENT)", "NEET UG DETAILS:", "PERCENTAGE (%)", "BIOLOGY", "CHEMISTRY", "PHYSICS", "SUBJECT", "CLASS XII DETAILS:", "YEAR OF PASSING", "%/CGPA|", "%/CGPA", "CLASS XII", "CLASS X", "INSTITUTE/BOARD", "PREVIOUS ACADEMIC QUALIFICATION:", "QUOTA:", "CATEGORY:", "ALL INDIA RANK:", "PERCENTILE:", "TOTAL MARKS OBTAINED:", "MARKS OBTAINED", "ROLL NO.:", "APPLICATION NO.:", "TOTAL MARKS:", "EXAMINATION", "TOTAL :", "DISTRICT:"

        ]



        cleaned_text = text

        for replacement in replacements:

            if replacement == "•":

                cleaned_text = cleaned_text.replace(replacement, ".")

            else:

                cleaned_text = cleaned_text.replace("MEDICAL COLLEGE", "").replace("ALL FOR EDUCATION, EDUCATION FOR ALL", "").replace("REG. OFFICE: A2/15, KALYANI, DIST.: NADIA,", "").replace("REG. OFFICE: A2/15, KALYANI, DIST: NADIA,", "").replace("ALL FOR EDUCATION, FUCATION FOR ALF", "").replace("RESPECTED SIR/MADAM,", "").replace("PARTICULARS ARE", "").replace("FURNISHED BELOW FOR YOUR KIND CONSIDERATION.", "").replace("PIN 741235, WEST BENGAL, INDIA", "").replace("MAIL ID: INFO.JMNEDUR@GMAIL.COM", "").replace("CONTACT NO: +91 9831111817", "").replace("CAMPUS: UTTAR PANCHPOTA, P.O & P. S. CHAKDAHA,", "").replace("DIST. NADIPIP INSTALLA, PIN 741222, WEST BENGAL, INDIA", "").replace("DIST. NADIA, PIN 741222, WEST BENGAL, INDIA", "FORM-START").replace("JMN", "").replace("ADMISSION FORM", "").replace("THE PRINCIPAL,", "").replace("JMN MEDICAL COLLEGE,", "").replace("UTTAR PANCHPOTA, P.O. & P.S. CHAKDAHA,", "").replace("DIST. NADIA, PINCODE - 741222,", "").replace("WEST BENGAL, INDIA.", "").replace("PASTE RECENT", "").replace("PASSPORT-SIZE", "").replace("COLOUR", "").replace("PHOTOGRAPH OF", "").replace("THE CANDIDATE", "").replace("AND SIGN ACROSS", "").replace("THE PHOTOGRAPH.", "").replace("RESPECTED SIR / MADAM,", "").replace("I HEREBY APPLY FOR ADMISSION TO THE MBBS COURSE IN SESSION", "MBBS COURSE IN SESSION:").replace("PARTICULARS ARE FURNISHED BELOW FOR YOUR KIND CONSIDERATION.", "").replace("KINDLY USE CAPITAL LETTERS ONLY", "").replace("JMN MEDICAL COLLEGE", "").replace("WWW.JMNMEDICALCOLLEGE.ORG.IN", "").replace("WWW.MEDICALCOLLEGE.ORG.IN", "").replace("AT THIS COLLEGE. NECESSARY", "").replace("@@", "@").replace("@GIMAIIL.COM", "@GMAIL.COM").replace("@GMIL.CO", "@GMAIL.COM").replace("P.O.:", "P.O.:").replace("P.O. :", "P.O.:").replace("PO:", "P.O.:").replace("P.O :", "P.O.:").replace("P.O:", "P.O.:").replace("P.S.:", "P.S.:").replace("P.S. :", "P.S.:").replace("PS.:", "P.S.:").replace("PS:", "P.S.:").replace("P.S :", "P.S.:").replace("P.S:", "P.S.:").replace("•", ".").replace("MOBILE NO.:", "MOBILE NO:").replace("MOBILE NO :", "MOBILE NO:").replace("WWW.JMMMEDICALCOLLEGE.ORG.IN", "") #.replace("STUDENT DETAILS:", "").replace("PARENT DETAILS:", "").replace("LOCAL GUARDIAN DETAILS: (IN CASE OF OUTSTATION STUDENT)", "").replace("QUALIFICATION DETAILS:", "")

                cleaned_text = cleaned_text.replace(replacement, "\n" + replacement)



        cleaned_lines = [line for line in cleaned_text.splitlines() if line.strip() != "" and line.strip() != "TO" and line.strip() != ","]

        cleaned_text = "\n".join(cleaned_lines)



        return cleaned_text

    except Exception as e:

        print(f"Text replacement failed: {e}")

        return text



def extract_human_picture(image_path):

    try:

        # Load the image

        img = cv2.imread(image_path)

        

        # Enhance the image to reduce haze and improve quality

        denoise_strength = 3  # Customizable denoise strength

        img = cv2.fastNlMeansDenoisingColored(img, None, denoise_strength, denoise_strength, 7, 21)  # Denoising to reduce haze

        # Increase contrast

        contrast_alpha = 1  # Customizable contrast control (1.0-3.0)

        brightness_beta = 5.5  # Customizable brightness control (0-100)

        img = cv2.convertScaleAbs(img, alpha=contrast_alpha, beta=brightness_beta) 

        

        # Load the pre-trained Haar Cascade classifier for face detection

        face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

        

        # Convert the image to grayscale for face detection

        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        

        # Detect faces in the image

        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)

        

        # If a face is detected, extract the first one

        if len(faces) > 0:

            (x, y, w, h) = faces[0]  # Get the coordinates of the first detected face

            

            # Extend the cropping area to include the full human picture

            x_extended = max(0, x - int(w * 0.5))  # Extend left by 50% of the width(extend left)

            y_extended = max(0, y - int(h * 0.5))  # Extend top by 50% of the height(extend Top)

            w_extended = int(w * 2.10)  # New width: 210% of the original width(extend Right)

            h_extended = int(h * 2.75)  # New height: 275% of the original height (extend down)

            

            face_image = img[y_extended:y_extended + h_extended, x_extended:x_extended + w_extended]  # Crop the full human picture from the image

            

            # Create extracted folder if it doesn't exist

            os.makedirs('extracted', exist_ok=True)

            

            # Save the extracted face image

            cv2.imwrite('extracted/extracted_face.jpg', face_image)

            return 'extracted/extracted_face.jpg'

        return None  # No face detected

    except Exception as e:

        print(f"Face extraction failed: {e}")

        return None

    

def extract_signature(image_path):

    try:

        # Load the image

        img = cv2.imread(image_path)

        

        # Convert to grayscale

        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        

        # Apply adaptive thresholding for better signature detection

        binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 

                                       cv2.THRESH_BINARY_INV, 11, 2)

        

        # Find contours of the signature

        contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        

        # Filter contours based on area to find the signature

        if contours:

            # Sort contours by their y-coordinate (bottom-most first)

            sorted_contours = sorted(contours, key=lambda c: cv2.boundingRect(c)[1], reverse=True)

            

            # Iterate through sorted contours to find the signature

            for contour in sorted_contours:

                area = cv2.contourArea(contour)

                # Adjust the threshold based on the image size

                threshold = int(img.shape[0] * img.shape[1] * 0.001)  # 0.1% of the image area

                if area > threshold:

                    x, y, w, h = cv2.boundingRect(contour)

                    # Reduce the border crop by adjusting the cropping dimensions

                    border_reduction = 0.05  # Reduce the border by 10%

                    x_extended = int(x - w * (border_reduction - 0.07))  # Extend left by 20% of the width

                    y_extended = int(y + h * border_reduction)

                    w_extended = int(w * (1 - border_reduction))  # Reduce width by 5%

                    h_extended = int(h * (1 - 2 * border_reduction))

                    signature_image = img[y_extended:y_extended + h_extended, x_extended:x_extended + w_extended]  # Crop the signature

                    

                    # Create extracted folder if it doesn't exist

                    os.makedirs('extracted', exist_ok=True)

                    

                    # Save the extracted signature image

                    cv2.imwrite('extracted/extracted_signature.jpg', signature_image)

                    return 'extracted/extracted_signature.jpg'

        return None  # No signature detected

    except Exception as e:

        print(f"Signature extraction failed: {e}")

        return None

@app.route('/upload', methods=['POST'])

def upload():

    try:

        # Clean uploads folder

        if os.path.exists('./uploads'):

            shutil.rmtree('./uploads')

        os.makedirs('./uploads')



        file = request.files.get('file_1')

        key = request.form.get('key_1')



        if not file:

            print("[ERROR] No file_1 received in upload endpoint.")

            return jsonify({

                "data": [],

                "img": {},

                "sig": {},

                "status": 500,

                "message": {"msg": "No file_1 received. Please select a file to upload."}

            }), 200

        if not key:

            print("[ERROR] No key_1 received in upload endpoint.")

            return jsonify({

                "data": [],

                "img": {},

                "sig": {},

                "status": 500,

                "message": {"msg": "No key_1 received. Please provide a key."}

            }), 200



        # ✅ Save file

        file_path = f"./uploads/{file.filename}"

        file.save(file_path)



        print("File saved:", file_path)



        # ✅ Extract face

        extracted_face_path = extract_human_picture(file_path)



        if not extracted_face_path:

            print("No face detected")

            extracted_face_path = file_path  # fallback



        # ✅ Save face to server

        server_path = f"/home/sigmente/public_html/sit/jmn/public/uploads/student_image/{key}_img.jpg"

        public_url = f"uploads/student_image/{key}_img.jpg"

        shutil.copy(extracted_face_path, server_path)



        print("Image stored at:", server_path)



        # ✅ Gemini extraction

        text = extract_text_with_gemini(file_path)



        if not text:

            print("Gemini returned empty")

            return jsonify({

                "data": {},

                "img": {},

                "sig": {},

                "status": 500,

                "message": {"msg": "Extraction failed"}

            }), 200



        print("RAW GEMINI:", text)



        parsed_data = parse_gemini_json(text)



        # SAFE data structure fallback for formStart/form_no

        if "formStart" not in parsed_data or not isinstance(parsed_data.get("formStart"), dict):

            parsed_data["formStart"] = {}



        parsed_data["formStart"]["form_no"] = parsed_data["formStart"].get("form_no") or key



        print("FINAL JSON SENT:", json.dumps(parsed_data, indent=2))



        # Save page1 data in memory (include the image URL too so upload_back can return it)

        TEMP_STORE[key] = {

            "data": parsed_data,

            "img": {"img": public_url}

        }



        return jsonify({

            "data": parsed_data,  # Include data for frontend

            "img": {"img": public_url},

            "sig": {},

            "status": 200,

            "message": {"msg": "Page 1 stored successfully"},

            "next_step": "upload_back"

        }), 200



    except Exception as e:

        print("ERROR:", str(e))



        return jsonify({

            "data": [],

            "img": {},

            "sig": {},

            "status": 500,

            "message": {"msg": "Server error"}

        }), 200



    finally:

        # Cleanup

        try:

            if 'file_path' in locals() and os.path.exists(file_path):

                os.remove(file_path)

        except:

            pass



@app.route('/upload_back', methods=['POST'])

def upload_back():

    try:

        # Delete the uploads directory if it exists

        if os.path.exists('./uploads'):

            shutil.rmtree('./uploads')

        

        # Create a new uploads directory

        os.makedirs('./uploads')



        # Set API key for back upload

        key1 = datetime.fromtimestamp(int("0x680b1c00", 16))

        file = request.files.get('file_2')  # Ensure the key matches what Laravel sends

        key = request.form.get('key_2')  # Get the key from the form data



        if not file:

            print("[ERROR] No file_2 received in upload_back endpoint.")

            return jsonify({

                "data": [],

                "img": {},

                "sig": {},

                "status": 500,

                "message": {"msg": "No file_2 received. Please select a file to upload."}

            }), 200

        if not key:

            print("[ERROR] No key_2 received in upload_back endpoint.")

            return jsonify({

                "data": [],

                "img": {},

                "sig": {},

                "status": 500,

                "message": {"msg": "No key_2 received. Please provide a key."}

            }), 200

        if file and key:

            f = datetime.now()

            file_path = f"./uploads/back_{file.filename}"

            file.save(file_path)

        

        # Get the image data from the request

        # image_data = request.get_data()

        

        # # Save the image data to a temporary file

        # file_path = f"./uploads/temp_image.jpg"

        # with open(file_path, 'wb') as f:

        #     f.write(image_data)

            

            # Extract signature from the uploaded image

            extracted_signature_path = extract_signature(file_path)

            if extracted_signature_path:

                print(f"Extracted signature image saved at: {extracted_signature_path}")



                # Save the extracted signature image with the key's text name

                #Save in production

                

                #Save in Sit

                server_path = f"/home/sigmente/public_html/sit/jmn/public/uploads/student_signature/{key}_sig.jpg"

                public_url = f"/uploads/student_signature/{key}_sig.jpg"

                #Save in local

                #new_file_path = f"C:/Users/Atanu Roy/Downloads/laravel/sig/{key}_img.jpg"



                shutil.copy(extracted_signature_path, server_path)  # Copy the extracted image to the new path

            else:

                print("No signature found")

                public_url = None



            # Always save the back page image

            server_back_path =f"/home/sigmente/public_html/sit/jmn/public/uploads/back_image/{key}_back.jpg"

            public_back_url =f"uploads/back_image/{key}_back.jpg"

            os.makedirs(os.path.dirname(server_back_path), exist_ok=True)

            shutil.copy(file_path, server_back_path)



            # Debugging: Check if the file is saved

            print(f"Signature file saved at: {server_path}")



            # First try to extract text using Gemini

            text = extract_text_with_back_gemini(file_path)

            if text:

                parsed_data = parse_gemini_json(text)



                # SAFE data structure fallback for formStart/form_no

                if "formStart" not in parsed_data or not isinstance(parsed_data.get("formStart"), dict):

                    parsed_data["formStart"] = {}



                if "form_no" not in parsed_data["formStart"] or parsed_data["formStart"].get("form_no") in [None, ""]:

                    parsed_data["formStart"]["form_no"] = key



                print("FINAL JSON SENT:", json.dumps(parsed_data, indent=2))



                # Get stored page1 data and image

                page1_record = TEMP_STORE.pop(key, {})

                page1_data = page1_record.get("data", {})

                page1_img = page1_record.get("img", {})



                # Merge both form JSON structures while preserving the original form_no from page1

                page1_form_start = page1_data.get("formStart", {}) if isinstance(page1_data.get("formStart"), dict) else {}

                parsed_form_start = parsed_data.get("formStart", {}) if isinstance(parsed_data.get("formStart"), dict) else {}

                final_form_no = page1_form_start.get("form_no") or parsed_form_start.get("form_no") or key



                merged_data = {

                    **page1_data,

                    **parsed_data,

                    "formStart": {

                        **page1_form_start,

                        **parsed_form_start,

                        "form_no": final_form_no

                    }

                }



                print("MERGED FINAL JSON:", json.dumps(merged_data, indent=2))



                front_url = page1_img.get("img") if page1_img else ""

                img_response = {

                    "img": front_url

                }

                sig_response = {"sig": public_url} if public_url else {}

                return jsonify({

                    "data": merged_data,

                    "img": img_response,

                    "sig": sig_response,

                    "status": 200

                }), 200

            else:

                print("Gemini extraction failed for back page.")

                return jsonify({"data": {}, "img": {}, "sig": {}, "status": 500, "message": {'msg':'Failed to extract text from Gemini for back page.'}}), 200

                        

        else:

            return jsonify({"data": [], "img": {}, "sig": {}, "status": 500, "message": {"msg": "Select Page 2"}}), 200

    except Exception as e:

        # Delete the uploaded file if it exists

        if 'file_path' in locals() and os.path.exists(file_path):  

            os.remove(file_path)

        return jsonify({"data": [], "img": {}, "sig": {}, "status": 500, "message": {'msg':'An error occurred during processing.'}}), 200

    finally:

        # Delete the temporary image file after processing

        try:

            if 'file_path' in locals() and os.path.exists(file_path):

                os.remove(file_path)

        except:

            pass





# ===== ROUTES AND MAIN =====



@app.route('/')

def index():

    try:

        return render_template('index.php')

    except Exception as e:

        print(f"Error rendering index: {e}")

        return "An error occurred", 200



@app.route('/favicon.ico')

def favicon():

    return '', 200  



if __name__ == "__main__":

    app.run(debug=True, host='0.0.0.0', port=6003)

