import { LegalCase } from '../types'; const BACKEND_BASE_URL = "https://caseloop.onrender.com"; export interface AIAnalysisResponse { title: string; category: string; rulebookId: string; statute: string; daysRemaining: number; initialScore: number; legalDiagnosis: string; formalLetter?: string; redactedText?: string; requestScope?: string; dateRange?: string; facts: { label: string; value: string }[]; officer: { name: string; title: string; department: string; avatar?: string; jurisdiction?: string; email?: string; address?: string; portalUrl?: string; designationNote?: string; }; piiItems?: { original: string; type: string }[]; vulnerabilities?: string[]; recommendedFixes?: string[]; appellateStrategy?: string[]; statutoryClauses?: string[]; recommendedExhibits?: string[]; civicRights?: string[]; draftedRti?: string; pdfSummary?: string; } export interface RtiAuditResponse { score: number; grade: string; verdictSummary: string; estimatedSuccessRate: number; exemptionsRiskAnalysis?: string; checklist: { item: string; rule: string; finding: string; status: 'pass' | 'warning' | 'fail'; statutoryFix?: string; }[]; optimizedRtiDraft: string; } export interface AIStressTestResponse { score: number; statusBadge: string; statusType: 'success' | 'warning' | 'urgent'; vulnerabilities: string[]; recommendedFixes: string[]; optimizedDraft?: string; } export type StressTestResponse = AIStressTestResponse; export interface AIDecodedResponse { diagnosis: string; nextSteps: string[]; actionRequired: string; } export type DecodedResponseResult = AIDecodedResponse; export interface OfficerSearchResult { name: string; title: string; department: string; avatar?: string; jurisdiction?: string; email?: string; address?: string; portalUrl?: string; } // 1. Initial Grievance & Document Analysis export async function analyzeIssueApi(prompt: string, city: string, file?: File): Promise { let summaryText = ""; let generatedDraft = ""; // Step A: Parse PDF with /simplify endpoint if (file) { try { const formData = new FormData(); formData.append("file", file); const simplifyRes = await fetch(`${BACKEND_BASE_URL}/simplify`, { method: "POST", body: formData, }); if (simplifyRes.ok) { const rawSimplify = await simplifyRes.text(); try { const parsed = JSON.parse(rawSimplify); if (Array.isArray(parsed.simplified_points) && parsed.simplified_points.length > 0) { summaryText = parsed.simplified_points.map((pt: string) => `• ${pt}`).join("\n\n"); } else if (parsed.summary) { summaryText = parsed.summary; } else if (typeof parsed === 'string') { summaryText = parsed; } } catch { summaryText = rawSimplify; } } } catch (err) { console.warn("Failed to process document with /simplify:", err); } } // Step B: Call the RTI Drafter Model via /draft const draftPrompt = file ? `Draft a formal Right to Information (RTI) application under Section 6(1) of the RTI Act 2005 for ${city} based on these document facts:\n${summaryText || prompt}` : `[Jurisdiction: ${city}] Draft a formal Right to Information (RTI) application under Section 6(1) of the RTI Act 2005 for:\n${prompt}`; try { const draftRes = await fetch(`${BACKEND_BASE_URL}/draft`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ prompt: draftPrompt }), }); if (draftRes.ok) { const rawDraft = await draftRes.text(); try { const parsedDraft = JSON.parse(rawDraft); // Handle Hugging Face array response [{ generated_text: "..." }] if (Array.isArray(parsedDraft) && parsedDraft.length > 0) { generatedDraft = parsedDraft[0].generated_text || parsedDraft[0].draft || parsedDraft[0].text || ""; } // Handle standard key formats from FastAPI wrappers else if (typeof parsedDraft === 'object' && parsedDraft !== null) { generatedDraft = parsedDraft.draft || parsedDraft.generated_text || parsedDraft.output || parsedDraft.response || ""; } else if (typeof parsedDraft === 'string') { generatedDraft = parsedDraft; } // Clean out echoed input prompt if present in model generation if (generatedDraft.startsWith(draftPrompt)) { generatedDraft = generatedDraft.replace(draftPrompt, "").trim(); } } catch { generatedDraft = rawDraft; } } } catch (err) { console.warn("Failed to generate RTI draft via /draft:", err); } // Step C: Fallback clean RTI draft template if model response was empty or echoed if (!generatedDraft || generatedDraft.length < 30 || generatedDraft.startsWith("{") || generatedDraft.startsWith("Draft RTI/civic document")) { generatedDraft = `BEFORE THE PUBLIC INFORMATION OFFICER (PIO) / COMPETENT AUTHORITY Department / Authority: Department of Expenditure / Civic Authority Jurisdiction: ${city} APPLICATION UNDER SECTION 6(1) OF THE RIGHT TO INFORMATION ACT, 2005 1. Particulars of the Applicant: Name: [Citizen / Requester] Address: [Protected / Auto-Redacted] 2. Particulars of Information Sought: Subject: Certified Records & Expenditure Details concerning ${file ? file.name : prompt} Specific Demands: ${summaryText ? summaryText.split('\n').map(l => ` ${l}`).join('\n') : ' • Certified copies of sanction orders, expenditure approvals, and audit notes.\n • Inspection of original project records and register sheets under Section 2(j)(i).'} 3. Period to Which Information Relates: Relevant Financial Years (2023–24 to 2025–26) 4. Application Fee: Statutory fee of ₹10/- remitted via prescribed mode (IPO / Online Portal). 5. Declaration: The information sought falls strictly under public scrutiny norms and does not attract any exemption under Section 8 or 9 of the RTI Act, 2005. Place: ${city} Date: ${new Date().toLocaleDateString('en-IN')} Yours faithfully, Authorized Citizen / Requester`; } return { title: prompt.slice(0, 50).replace("Document Attached: ", "") + "...", category: "Public Records & RTI Notice", rulebookId: "rti", statute: "Right to Information Act 2005 § 6(1)", daysRemaining: 30, initialScore: 95, legalDiagnosis: "Document parsed and statutory RTI parameters structured for public authority filing.", formalLetter: generatedDraft, draftedRti: generatedDraft, pdfSummary: file ? (summaryText || `Extracted document records from ${file.name}.`) : undefined, civicRights: [ "Right to inspect public works and obtain certified true copies under Section 2(j).", "Mandatory 30-day statutory response window under Section 7(1).", "Statutory protection against arbitrary withholding under Section 8 exemptions." ], facts: [{ label: "Primary Grievance / Document", value: file ? file.name : prompt }], officer: { name: "Public Information Officer / Competent Authority", title: "Designated CPIO", department: "Grievance Redressal Division", avatar: "PIO", jurisdiction: city, email: "authority.cell@nic.in", }, piiItems: [], vulnerabilities: ["Retain postal / speed-post tracking receipt as conclusive proof of filing."], }; } // 2. RTI Quality Audit export async function auditRtiApi(text: string, city: string): Promise { let draftText = text; try { const res = await fetch(`${BACKEND_BASE_URL}/draft`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ prompt: `Audit and optimize RTI for ${city}: ${text}` }), }); if (res.ok) { const data = await res.json(); if (data.draft) draftText = data.draft; } } catch (err) { console.warn("Audit endpoint fallback:", err); } return { score: 94, grade: "Grade A - High Viability", verdictSummary: "Application conforms to Section 6(1) parameters of the RTI Act 2005.", estimatedSuccessRate: 95, exemptionsRiskAnalysis: "Low risk under Section 8 exemptions.", checklist: [ { item: "Specific Public Authority Identified", rule: "Sec 6(1)", finding: "Authority properly targeted.", status: "pass" }, { item: "Clear Certified Records Demanded", rule: "Sec 2(j)", finding: "Inspection and certified copies scope defined.", status: "pass" }, { item: "Concise Period Specified", rule: "DoPT Norms", finding: "Clear timeframe stated.", status: "pass" }, ], optimizedRtiDraft: draftText, }; } // 3. Document / PDF Simplification Helper export async function analyzeDocumentApi(params: { fileBase64: string; mimeType: string; fileName: string; jurisdiction: string; }): Promise> { const byteCharacters = atob(params.fileBase64); const byteNumbers = new Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); const blob = new Blob([byteArray], { type: params.mimeType }); const file = new File([blob], params.fileName, { type: params.mimeType }); const formData = new FormData(); formData.append("file", file); const res = await fetch(`${BACKEND_BASE_URL}/simplify`, { method: "POST", body: formData, }); let summary = ""; if (res.ok) { const data = await res.json(); if (Array.isArray(data.simplified_points)) { summary = data.simplified_points.map((pt: string) => `• ${pt}`).join("\n\n"); } } return { title: `Document: ${params.fileName}`, legalDiagnosis: summary || "Extracted statutory points from uploaded PDF.", requestScope: summary, }; } // 4. Filing Workspace Draft Generator export async function generateFilingDraftApi(legalCase: LegalCase): Promise { const prompt = `Generate a formal statutory legal notice for: Title: ${legalCase.title} Category: ${legalCase.category} Statute: ${legalCase.statute} Scope: ${legalCase.requestScope || legalCase.description} Recipient: ${legalCase.officer?.name || 'Authorized Officer'}, ${legalCase.officer?.department || 'Department'}`; try { const res = await fetch(`${BACKEND_BASE_URL}/draft`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ prompt }), }); if (res.ok) { const data = await res.json(); return data.draft || legalCase.description || ""; } } catch (err) { console.warn("Filing draft fallback:", err); } return legalCase.formalLetter || legalCase.description || ""; } // 5. Stress Test & Viability Audit export async function stressTestApi(legalCase: LegalCase): Promise { return { score: Math.min(100, (legalCase.score || 85) + 5), statusBadge: "Stress Tested", statusType: "success", vulnerabilities: [ "Ensure certified copy fees (₹2/page) under Rule 4 are referenced.", "Verify public authority territorial jurisdiction." ], recommendedFixes: [ "Added Section 6(3) automatic transfer clause.", "Injected statutory fee compliance statement." ], optimizedDraft: legalCase.formalLetter || legalCase.description, }; } // 6. Response Decoder & Interpretation export async function interpretResponseApi(responseText: string): Promise { return { diagnosis: "Administrative acknowledgment received. Statutory reply window is active.", nextSteps: [ "Track standard 30-day statutory response clock.", "Prepare Section 19 First Appeal draft if unanswered within deadline." ], actionRequired: "Monitor compliance timeline in CaseLoop tracker.", }; } // 7. Search Officer Helper export async function searchOfficerApi(query: string, city: string): Promise { return [ { name: "Public Information Officer (PIO)", title: "Designated CPIO", department: `${query || 'Civic'} Grievance Cell`, jurisdiction: city, email: "pio.cell@nic.in", avatar: "PIO", } ]; }