import { getDb } from "../../../db";
import { requireSession } from "../../auth-server";
const num=(v:unknown)=>Number(v)||0,nullable=(v:unknown)=>v?Number(v):null;
const first=<T,>(rows:unknown)=>((rows as T[])||[])[0];
export async function GET(request:Request){const auth=await requireSession(request);if(auth.response)return auth.response;try{const db=getDb();const [clientsR,projectsR,entriesR,assetsR,projectionsR,approvalsR]=await Promise.all([
 db.query("SELECT id,company,contact,phone,email,address,tax_id taxId,created_at createdAt FROM clients ORDER BY company"),
 db.query("SELECT p.id,p.code,p.name,p.service_type serviceType,p.client_id clientId,c.company clientName,p.contract_value contractValue,p.budget,p.progress,p.status,p.start_date startDate,p.end_date endDate,p.created_at createdAt FROM projects p LEFT JOIN clients c ON c.id=p.client_id ORDER BY p.id DESC"),
 db.query("SELECT f.id,f.date,f.due_date dueDate,f.document_no documentNo,f.category,f.direction,f.description,f.amount,f.paid_amount paidAmount,f.notification_dismissed notificationDismissed,f.status,f.project_id projectId,f.client_id clientId,f.notes,f.created_at createdAt,p.name projectName,c.company clientName FROM finance_entries f LEFT JOIN projects p ON p.id=f.project_id LEFT JOIN clients c ON c.id=f.client_id ORDER BY f.date DESC,f.id DESC"),
 db.query("SELECT id,code,name,category,acquisition_date acquisitionDate,acquisition_value acquisitionValue,useful_life usefulLife,`condition`,location,created_at createdAt FROM assets ORDER BY acquisition_date DESC"),
 db.query("SELECT id,period,scenario,projected_income projectedIncome,projected_expense projectedExpense,notes,created_at createdAt FROM projections ORDER BY period"),
 db.query("SELECT id,report_type reportType,period,status,approved_by approvedBy,approved_at approvedAt,notes FROM approvals ORDER BY approved_at DESC")
 ]);return Response.json({clients:clientsR[0],projects:projectsR[0],entries:entriesR[0],assets:assetsR[0],projections:projectionsR[0],approvals:approvalsR[0]});}catch(e){return Response.json({error:e instanceof Error?e.message:"Database gagal dibaca",clients:[],projects:[],entries:[],assets:[],projections:[],approvals:[]},{status:500})}}

export async function POST(request:Request){const auth=await requireSession(request);if(auth.response)return auth.response;try{const p=await request.json() as Record<string,unknown>,kind=String(p.kind||""),db=getDb();
 if(kind==="approval"){if(auth.session.role!=="director")return Response.json({error:"Hanya Direktur yang dapat menyetujui laporan."},{status:403});const reportType=String(p.reportType||""),period=String(p.period||"");if(!["Neraca","Laba Rugi"].includes(reportType)||!/^\d{4}-\d{2}$/.test(period))return Response.json({error:"Jenis laporan atau periode tidak valid."},{status:400});await db.execute("INSERT INTO approvals(report_type,period,status,approved_by,approved_at,notes) VALUES(?,?,'Disetujui',?,NOW(),?) ON DUPLICATE KEY UPDATE status='Disetujui',approved_by=VALUES(approved_by),approved_at=NOW(),notes=VALUES(notes)",[reportType,period,auth.session.name,String(p.notes||"")]);return Response.json({reportType,period,status:"Disetujui",approvedBy:auth.session.name});}
 if(auth.session.role!=="manager")return Response.json({error:"Akun Direktur hanya dapat melihat dan menyetujui laporan."},{status:403});
 if(kind==="client"){if(!p.company)return Response.json({error:"Nama perusahaan wajib diisi"},{status:400});const [r]=await db.execute("INSERT INTO clients(company,contact,phone,email,address,tax_id) VALUES(?,?,?,?,?,?)",[String(p.company),String(p.contact||""),String(p.phone||""),String(p.email||""),String(p.address||""),String(p.taxId||"")]);return Response.json({id:(r as {insertId:number}).insertId},{status:201});}
 if(kind==="project"){if(!p.name)return Response.json({error:"Nama proyek wajib diisi"},{status:400});const [mx]=await db.query("SELECT COALESCE(MAX(id),0)+1 nextId FROM projects"),next=first<{nextId:number}>(mx)?.nextId||1,code=`PRJ-${new Date().getFullYear()}-${String(next).padStart(4,"0")}`;const [r]=await db.execute("INSERT INTO projects(code,name,service_type,client_id,contract_value,budget,progress,status,start_date,end_date) VALUES(?,?,?,?,?,?,?,?,?,?)",[code,String(p.name),String(p.serviceType||""),nullable(p.clientId),num(p.contractValue),num(p.budget),num(p.progress),String(p.status||"Berjalan"),String(p.startDate||""),String(p.endDate||"")]);return Response.json({id:(r as {insertId:number}).insertId,code},{status:201});}
 if(kind==="projectUpdate"){const id=num(p.id);if(!id||!p.name)return Response.json({error:"Proyek dan nama proyek wajib diisi"},{status:400});const [r]=await db.execute("UPDATE projects SET name=?,service_type=?,contract_value=?,budget=?,progress=?,status=?,start_date=?,end_date=? WHERE id=?",[String(p.name),String(p.serviceType||""),num(p.contractValue),num(p.budget),Math.min(100,Math.max(0,num(p.progress))),String(p.status||"Berjalan"),String(p.startDate||""),String(p.endDate||""),id]);if(!(r as {affectedRows:number}).affectedRows)return Response.json({error:"Proyek tidak ditemukan"},{status:404});return Response.json({id});}
 if(kind==="asset"){const [mx]=await db.query("SELECT COALESCE(MAX(id),0)+1 nextId FROM assets"),next=first<{nextId:number}>(mx)?.nextId||1,code=`AST-${new Date().getFullYear()}-${String(next).padStart(4,"0")}`;const [r]=await db.execute("INSERT INTO assets(code,name,category,acquisition_date,acquisition_value,useful_life,`condition`,location) VALUES(?,?,?,?,?,?,?,?)",[code,String(p.name||""),String(p.category||""),String(p.acquisitionDate||""),num(p.acquisitionValue),num(p.usefulLife)||4,String(p.condition||"Baik"),String(p.location||"")]);return Response.json({id:(r as {insertId:number}).insertId,code},{status:201});}
 if(kind==="projection"){const [r]=await db.execute("INSERT INTO projections(period,scenario,projected_income,projected_expense,notes) VALUES(?,?,?,?,?)",[String(p.period||""),String(p.scenario||"Moderat"),num(p.projectedIncome),num(p.projectedExpense),String(p.notes||"")]);return Response.json({id:(r as {insertId:number}).insertId},{status:201});}
 if(kind==="entry"){if(!p.date||!p.description)return Response.json({error:"Tanggal dan uraian wajib diisi"},{status:400});const [mx]=await db.query("SELECT COALESCE(MAX(id),0)+1 nextId FROM finance_entries"),next=first<{nextId:number}>(mx)?.nextId||1,documentNo=`TRX-${new Date().getFullYear()}-${String(next).padStart(5,"0")}`;const [r]=await db.execute("INSERT INTO finance_entries(date,due_date,document_no,category,direction,description,amount,paid_amount,status,project_id,client_id,notes) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)",[String(p.date),String(p.dueDate||""),documentNo,String(p.category||""),String(p.direction||""),String(p.description),num(p.amount),num(p.paidAmount),String(p.status||"Draft"),nullable(p.projectId),nullable(p.clientId),String(p.notes||"")]);return Response.json({id:(r as {insertId:number}).insertId,documentNo},{status:201});}
 if(kind==="entryStatus"){const id=num(p.id),status=String(p.status||"Draft"),paid=status==="Telah Dibayarkan"?num(p.amount):num(p.paidAmount);const [r]=await db.execute("UPDATE finance_entries SET status=?,paid_amount=? WHERE id=?",[status,paid,id]);if(!(r as {affectedRows:number}).affectedRows)return Response.json({error:"Transaksi tidak ditemukan"},{status:404});return Response.json({id,status,paidAmount:paid});}
 return Response.json({error:"Jenis data tidak dikenal"},{status:400});
 }catch(e){return Response.json({error:e instanceof Error?e.message:"Gagal menyimpan data"},{status:500})}}

export async function DELETE(request:Request){const auth=await requireSession(request,"manager");if(auth.response)return auth.response;try{const u=new URL(request.url),kind=u.searchParams.get("kind"),id=Number(u.searchParams.get("id")),db=getDb();if(!id||!["client","project","entry","notification"].includes(kind||""))return Response.json({error:"Target hapus tidak valid"},{status:400});if(kind==="notification"){await db.execute("UPDATE finance_entries SET notification_dismissed=1 WHERE id=?",[id]);return Response.json({ok:true});}if(kind==="entry"){const [rows]=await db.query("SELECT document_no documentNo FROM finance_entries WHERE id=? LIMIT 1",[id]),row=first<{documentNo:string}>(rows);if(!row)return Response.json({error:"Transaksi tidak ditemukan"},{status:404});if(row.documentNo&&!row.documentNo.startsWith("TRX-"))return Response.json({error:"Transaksi berasal dari dokumen dan harus dihapus dari arsip."},{status:409});await db.execute("DELETE FROM finance_entries WHERE id=?",[id]);return Response.json({ok:true});}if(kind==="client"){const [rows]=await db.query("SELECT (SELECT COUNT(*) FROM projects WHERE client_id=?) + (SELECT COUNT(*) FROM finance_entries WHERE client_id=?) + (SELECT COUNT(*) FROM commercial_documents WHERE client_id=?) total",[id,id,id]);if(num(first<{total:number}>(rows)?.total))return Response.json({error:"Klien masih terhubung dengan proyek atau transaksi."},{status:409});await db.execute("DELETE FROM clients WHERE id=?",[id]);return Response.json({ok:true});}const [rows]=await db.query("SELECT (SELECT COUNT(*) FROM finance_entries WHERE project_id=?) + (SELECT COUNT(*) FROM commercial_documents WHERE project_id=?) total",[id,id]);if(num(first<{total:number}>(rows)?.total))return Response.json({error:"Proyek masih memiliki transaksi atau dokumen."},{status:409});await db.execute("DELETE FROM projects WHERE id=?",[id]);return Response.json({ok:true});}catch(e){return Response.json({error:e instanceof Error?e.message:"Gagal menghapus data"},{status:500})}}
