<cfcomponent displayname="Problems AI API" hint="REST API for problems_ai table operations" output="true">
    
    <!--- Add CORS headers --->
    <cfheader name="Access-Control-Allow-Origin" value="*">
    <cfheader name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE">
    <cfheader name="Access-Control-Allow-Headers" value="Content-Type, Authorization">
    
    <!--- Set password encryption key (same as main application) --->
    <cfset this.passwordEncryptKey = "WTq8zYcZfaWVvMncigHqwQ==" />
    
    <!--- Validate Basic Authentication --->
    <cffunction name="validateBasicAuth" access="private" returntype="struct" hint="Validate HTTP Basic Authentication">
        <cfargument name="Agency_ID" required="yes" hint="Agency ID">
        
        <cfset var result = {
            "valid": false,
            "message": "Authentication required",
            "agency_db": "",
            "emp_id": 0
        } />
        
        <cftry>
            <!--- Get Authorization header --->
            <cfset var authHeader = getHttpRequestData().headers />
            
            <cfif not structKeyExists(authHeader, "Authorization") and not structKeyExists(authHeader, "authorization")>
                <cfheader statuscode="401" statustext="Unauthorized">
                <cfheader name="WWW-Authenticate" value="Basic realm=""API Access""">
                <cfset result.message = "Authorization header required" />
                <cfreturn result />
            </cfif>
            
            <!--- Get the authorization value (case insensitive) --->
            <cfset var authValue = "" />
            <cfif structKeyExists(authHeader, "Authorization")>
                <cfset authValue = authHeader.Authorization />
            <cfelse>
                <cfset authValue = authHeader.authorization />
            </cfif>
            
            <!--- Check if it's Basic auth --->
            <cfif not findNoCase("Basic ", authValue)>
                <cfheader statuscode="401" statustext="Unauthorized">
                <cfset result.message = "Basic Authentication required" />
                <cfreturn result />
            </cfif>
            
            <!--- Decode Base64 credentials --->
            <cfset var encodedCredentials = replaceNoCase(authValue, "Basic ", "") />
            <cfset var decodedCredentials = toString(toBinary(encodedCredentials)) />
            
            <!--- Split username and password --->
            <cfif not find(":", decodedCredentials)>
                <cfheader statuscode="401" statustext="Unauthorized">
                <cfset result.message = "Invalid credentials format" />
                <cfreturn result />
            </cfif>
            
            <cfset var username = listFirst(decodedCredentials, ":") />
            <cfset var password = listLast(decodedCredentials, ":") />
            
            <!--- Encrypt password for comparison --->
            <cfset var encryptedPassword = encrypt(password, this.passwordEncryptKey, "AES", "Base64") />
            
            <!--- Validate credentials against database --->
            <cfquery name="validateUser" datasource="#Application.DataSrc#">
                SELECT pEmployee.Emp_ID, pEmployee.Emp_First, pEmployee.Emp_Last, 
                       pEmployee.Loc_ID, Agency.Agency_Login
                FROM hhapowerpath.pEmployee
                JOIN hhapowerpath.Agency ON Agency.Agency_ID = pEmployee.Loc_ID
                WHERE pEmployee.Username = <cfqueryparam value="#username#" cfsqltype="cf_sql_varchar">
                AND pEmployee.Password = <cfqueryparam value="#encryptedPassword#" cfsqltype="cf_sql_varchar">
                AND pEmployee.Emp_Type = 'Employee'
                AND pEmployee.Status = 0
                AND pEmployee.Loc_ID = <cfqueryparam value="#arguments.Agency_ID#" cfsqltype="cf_sql_integer">
            </cfquery>
            
            <cfif validateUser.recordcount eq 0>
                <cfheader statuscode="401" statustext="Unauthorized">
                <cfset result.message = "Invalid username or password" />
                <cfreturn result />
            </cfif>
            
            <!--- Set agency database --->
            <cfset result.agency_db = 'agency_' & arguments.Agency_ID />
            
            <!--- Validate agency database exists --->
            <cfquery name="checkDBExistence" datasource="#Application.DataSrc#">
                SELECT SCHEMA_NAME FROM information_schema.schemata 
                WHERE SCHEMA_NAME = <cfqueryparam value="#result.agency_db#" cfsqltype="cf_sql_varchar">
            </cfquery>
            
            <cfif checkDBExistence.recordcount eq 0>
                <cfset result.message = "Invalid Agency ID - Database does not exist" />
                <cfreturn result />
            </cfif>
            
            <!--- Authentication successful --->
            <cfset result.valid = true />
            <cfset result.message = "Authentication successful" />
            <cfset result.emp_id = validateUser.Emp_ID />
            
            <cfcatch type="any">
                <cfheader statuscode="500" statustext="Internal Server Error">
                <cfset result.valid = false />
                <cfset result.message = "Authentication error: " & cfcatch.message />
            </cfcatch>
        </cftry>
        
        <cfreturn result />
    </cffunction>
    
    <!--- Insert single problem record --->
    <cffunction name="insertProblem" access="remote" returnformat="JSON" hint="Insert a single problem_ai record">
        <cfargument name="Agency_ID" required="yes" hint="Agency ID">
        <cfargument name="Patient_AI_ID" required="yes" hint="Patient AI ID">
        <cfargument name="Assmt_ID" required="yes" hint="Assessment ID">
        <cfargument name="Status" required="no" default="0" hint="Status">
        <cfargument name="M0_No" required="no" default="" hint="M0 Number">
        <cfargument name="Description" required="no" default="" hint="Problem Description">
        <cfargument name="Answer" required="no" default="" hint="Answer">
        <cfargument name="Severity" required="no" default="" hint="Severity Level">
        <cfargument name="dx_order" required="no" default="0" hint="Diagnosis Order">
        <cfargument name="Oasis_Deficits" required="no" default="" hint="OASIS Deficits">
        
        <cfset var response = {} />
        
        <cftry>
            <!--- Validate Basic Authentication --->
            <cfset var authResult = validateBasicAuth(arguments.Agency_ID) />
            
            <cfif not authResult.valid>
                <cfset response = {
                    "success": false,
                    "message": authResult.message,
                    "data": {}
                } />
                <cfreturn serializeJSON(response) />
            </cfif>
            
            <cfset var agency_db = authResult.agency_db />
            <cfset var created_by = authResult.emp_id />
            
            <!--- Insert the problem record --->
            <cfquery name="InsertProblem" datasource="#Application.DataSrc#" result="insertResult">
                INSERT INTO #agency_db#.problems_ai (
                    Patient_AI_ID,
                    Assmt_ID,
                    Status,
                    M0_No,
                    Description,
                    Answer,
                    Severity,
                    dx_order,
                    Oasis_Deficits,
                    Date_Create,
                    Created_by,
                    Date_Change,
                    Change_by,
                    record_timestamp
                ) VALUES (
                    <cfqueryparam value="#arguments.Patient_AI_ID#" cfsqltype="cf_sql_integer">,
                    <cfqueryparam value="#arguments.Assmt_ID#" cfsqltype="cf_sql_integer">,
                    <cfqueryparam value="#arguments.Status#" cfsqltype="cf_sql_tinyint">,
                    <cfqueryparam value="#arguments.M0_No#" cfsqltype="cf_sql_varchar" null="#len(trim(arguments.M0_No)) eq 0#">,
                    <cfqueryparam value="#arguments.Description#" cfsqltype="cf_sql_longvarchar" null="#len(trim(arguments.Description)) eq 0#">,
                    <cfqueryparam value="#arguments.Answer#" cfsqltype="cf_sql_longvarchar" null="#len(trim(arguments.Answer)) eq 0#">,
                    <cfqueryparam value="#arguments.Severity#" cfsqltype="cf_sql_varchar" null="#len(trim(arguments.Severity)) eq 0#">,
                    <cfqueryparam value="#arguments.dx_order#" cfsqltype="cf_sql_integer" null="#len(trim(arguments.dx_order)) eq 0 or arguments.dx_order eq 0#">,
                    <cfqueryparam value="#arguments.Oasis_Deficits#" cfsqltype="cf_sql_longvarchar" null="#len(trim(arguments.Oasis_Deficits)) eq 0#">,
                    <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">,
                    <cfqueryparam value="#created_by#" cfsqltype="cf_sql_integer">,
                    <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">,
                    <cfqueryparam value="#created_by#" cfsqltype="cf_sql_integer">,
                    <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
                )
            </cfquery>
            
            <!--- Get the inserted record --->
            <cfset insertedID = insertResult.GENERATED_KEY />
            
            <cfquery name="GetInsertedRecord" datasource="#Application.DataSrc#">
                SELECT * FROM #agency_db#.problems_ai
                WHERE Problem_ID = <cfqueryparam value="#insertedID#" cfsqltype="cf_sql_integer">
            </cfquery>
            
            <!--- Build success response --->
            <cfset response = {
                "success": true,
                "message": "Problem record inserted successfully",
                "data": {
                    "Problem_ID": GetInsertedRecord.Problem_ID,
                    "Patient_AI_ID": GetInsertedRecord.Patient_AI_ID,
                    "Assmt_ID": GetInsertedRecord.Assmt_ID,
                    "Status": GetInsertedRecord.Status,
                    "M0_No": GetInsertedRecord.M0_No,
                    "Description": GetInsertedRecord.Description,
                    "Answer": GetInsertedRecord.Answer,
                    "Severity": GetInsertedRecord.Severity,
                    "dx_order": GetInsertedRecord.dx_order,
                    "Oasis_Deficits": GetInsertedRecord.Oasis_Deficits,
                    "Date_Create": dateFormat(GetInsertedRecord.Date_Create, "yyyy-mm-dd") & " " & timeFormat(GetInsertedRecord.Date_Create, "HH:mm:ss"),
                    "Created_by": GetInsertedRecord.Created_by
                }
            } />
            
            <cfcatch type="any">
                <cfset response = {
                    "success": false,
                    "message": "Failed to insert problem record",
                    "error": cfcatch.message,
                    "detail": cfcatch.detail,
                    "data": {}
                } />
            </cfcatch>
        </cftry>
        
        <cfreturn serializeJSON(response) />
    </cffunction>
    
    <!--- Batch insert multiple problem records --->
    <cffunction name="batchInsertProblems" access="remote" returnformat="JSON" hint="Insert multiple problem_ai records">
        <cfargument name="Agency_ID" required="yes" hint="Agency ID">
        <cfargument name="problems_data" required="yes" hint="JSON array of problem records">
        
        <cfset var response = {} />
        <cfset var insertedCount = 0 />
        <cfset var failedCount = 0 />
        <cfset var insertedIDs = [] />
        <cfset var errors = [] />
        
        <cftry>
            <!--- Validate Basic Authentication --->
            <cfset var authResult = validateBasicAuth(arguments.Agency_ID) />
            
            <cfif not authResult.valid>
                <cfset response = {
                    "success": false,
                    "message": authResult.message,
                    "data": {
                        "inserted_count": 0,
                        "failed_count": 0,
                        "inserted_ids": [],
                        "errors": [authResult.message]
                    }
                } />
                <cfreturn serializeJSON(response) />
            </cfif>
            
            <cfset var agency_db = authResult.agency_db />
            <cfset var created_by = authResult.emp_id />
            
            <!--- Parse JSON data --->
            <cfif isJSON(arguments.problems_data)>
                <cfset dataArray = deserializeJSON(arguments.problems_data) />
            <cfelse>
                <cfset dataArray = arguments.problems_data />
            </cfif>
            
            <!--- Loop through each record --->
            <cfloop array="#dataArray#" index="idx" item="record">
                <cftry>
                    <!--- Validate required fields --->
                    <cfif not structKeyExists(record, "Patient_AI_ID") or len(trim(record.Patient_AI_ID)) eq 0>
                        <cfset arrayAppend(errors, "Record #idx#: Patient_AI_ID is required") />
                        <cfset failedCount++ />
                        <cfcontinue />
                    </cfif>
                    
                    <cfif not structKeyExists(record, "Assmt_ID") or len(trim(record.Assmt_ID)) eq 0>
                        <cfset arrayAppend(errors, "Record #idx#: Assmt_ID is required") />
                        <cfset failedCount++ />
                        <cfcontinue />
                    </cfif>
                    
                    <!--- Set defaults --->
                    <cfparam name="record.Status" default="0" />
                    <cfparam name="record.M0_No" default="" />
                    <cfparam name="record.Description" default="" />
                    <cfparam name="record.Answer" default="" />
                    <cfparam name="record.Severity" default="" />
                    <cfparam name="record.dx_order" default="0" />
                    <cfparam name="record.Oasis_Deficits" default="" />
                    
                    <!--- Insert the record --->
                    <cfquery name="InsertProblem" datasource="#Application.DataSrc#" result="insertResult">
                        INSERT INTO #agency_db#.problems_ai (
                            Patient_AI_ID, Assmt_ID, Status, M0_No, Description, Answer, 
                            Severity, dx_order, Oasis_Deficits, Date_Create, Created_by, 
                            Date_Change, Change_by, record_timestamp
                        ) VALUES (
                            <cfqueryparam value="#record.Patient_AI_ID#" cfsqltype="cf_sql_integer">,
                            <cfqueryparam value="#record.Assmt_ID#" cfsqltype="cf_sql_integer">,
                            <cfqueryparam value="#record.Status#" cfsqltype="cf_sql_tinyint">,
                            <cfqueryparam value="#record.M0_No#" cfsqltype="cf_sql_varchar" null="#len(trim(record.M0_No)) eq 0#">,
                            <cfqueryparam value="#record.Description#" cfsqltype="cf_sql_longvarchar" null="#len(trim(record.Description)) eq 0#">,
                            <cfqueryparam value="#record.Answer#" cfsqltype="cf_sql_longvarchar" null="#len(trim(record.Answer)) eq 0#">,
                            <cfqueryparam value="#record.Severity#" cfsqltype="cf_sql_varchar" null="#len(trim(record.Severity)) eq 0#">,
                            <cfqueryparam value="#record.dx_order#" cfsqltype="cf_sql_integer" null="#len(trim(record.dx_order)) eq 0 or record.dx_order eq 0#">,
                            <cfqueryparam value="#record.Oasis_Deficits#" cfsqltype="cf_sql_longvarchar" null="#len(trim(record.Oasis_Deficits)) eq 0#">,
                            <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">,
                            <cfqueryparam value="#created_by#" cfsqltype="cf_sql_integer">,
                            <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">,
                            <cfqueryparam value="#created_by#" cfsqltype="cf_sql_integer">,
                            <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
                        )
                    </cfquery>
                    
                    <cfset arrayAppend(insertedIDs, insertResult.GENERATED_KEY) />
                    <cfset insertedCount++ />
                    
                    <cfcatch type="any">
                        <cfset arrayAppend(errors, "Record #idx#: " & cfcatch.message) />
                        <cfset failedCount++ />
                    </cfcatch>
                </cftry>
            </cfloop>
            
            <!--- Build response --->
            <cfset response = {
                "success": (insertedCount gt 0),
                "message": "Batch insert completed: #insertedCount# succeeded, #failedCount# failed",
                "data": {
                    "inserted_count": insertedCount,
                    "failed_count": failedCount,
                    "inserted_ids": insertedIDs,
                    "errors": errors
                }
            } />
            
            <cfcatch type="any">
                <cfset response = {
                    "success": false,
                    "message": "Batch insert failed",
                    "error": cfcatch.message,
                    "data": {
                        "inserted_count": 0,
                        "failed_count": 0,
                        "inserted_ids": [],
                        "errors": [cfcatch.message]
                    }
                } />
            </cfcatch>
        </cftry>
        
        <cfreturn serializeJSON(response) />
    </cffunction>
    
    <!--- Get problem records by Patient AI ID --->
    <cffunction name="getProblemsByPatient" access="remote" returnformat="JSON" hint="Get all problems for a patient">
        <cfargument name="Agency_ID" required="yes" hint="Agency ID">
        <cfargument name="Patient_AI_ID" required="yes" hint="Patient AI ID">
        
        <cfset var response = {} />
        <cfset var problemsList = [] />
        
        <cftry>
            <!--- Validate Basic Authentication --->
            <cfset var authResult = validateBasicAuth(arguments.Agency_ID) />
            
            <cfif not authResult.valid>
                <cfset response = {
                    "success": false,
                    "message": authResult.message,
                    "data": []
                } />
                <cfreturn serializeJSON(response) />
            </cfif>
            
            <cfset var agency_db = authResult.agency_db />
            
            <!--- Get problems --->
            <cfquery name="GetProblems" datasource="#Application.DataSrc#">
                SELECT * FROM #agency_db#.problems_ai
                WHERE Patient_AI_ID = <cfqueryparam value="#arguments.Patient_AI_ID#" cfsqltype="cf_sql_integer">
                ORDER BY Date_Create DESC
            </cfquery>
            
            <cfif GetProblems.recordcount gt 0>
                <cfloop query="GetProblems">
                    <cfset obj = {
                        "Problem_ID": GetProblems.Problem_ID,
                        "Patient_AI_ID": GetProblems.Patient_AI_ID,
                        "Assmt_ID": GetProblems.Assmt_ID,
                        "Status": GetProblems.Status,
                        "M0_No": GetProblems.M0_No,
                        "Description": GetProblems.Description,
                        "Answer": GetProblems.Answer,
                        "Severity": GetProblems.Severity,
                        "dx_order": GetProblems.dx_order,
                        "Oasis_Deficits": GetProblems.Oasis_Deficits,
                        "Date_Create": dateFormat(GetProblems.Date_Create, "yyyy-mm-dd") & " " & timeFormat(GetProblems.Date_Create, "HH:mm:ss"),
                        "Created_by": GetProblems.Created_by
                    } />
                    <cfset arrayAppend(problemsList, obj) />
                </cfloop>
            </cfif>
            
            <cfset response = {
                "success": true,
                "message": "Found #GetProblems.recordcount# problem record(s)",
                "data": problemsList
            } />
            
            <cfcatch type="any">
                <cfset response = {
                    "success": false,
                    "message": "Failed to retrieve problem records",
                    "error": cfcatch.message,
                    "data": []
                } />
            </cfcatch>
        </cftry>
        
        <cfreturn serializeJSON(response) />
    </cffunction>
    
</cfcomponent>

