/*
 * File: src/main/java/reports/controller/KPIController.java
 * Description: This controller handles requests related to various Key Performance Indicators (KPIs)
 * in the ERP application. It provides endpoints for generating KPIs based on sales, purchases, suppliers,
 * taxes, patient prescriptions, financials, inventory, and audit compliance.
 *
 * Key Components:
 *
 * - **@RestController**: Indicates that this class is a Spring MVC controller where every method returns a domain object
 *   instead of a view. It combines **@Controller** and **@ResponseBody**.
 *
 * - **@RequestMapping**: Specifies the base URI for all endpoints in this controller. Here, it is set to "/api/kpi".
 *
 * - **@Autowired**: Automatically injects instances of service classes responsible for handling the business logic
 *   for different KPIs, allowing this controller to delegate the work to these services.
 *
 * - **@GetMapping**: Maps HTTP GET requests to specific methods in the controller, allowing retrieval of KPI data.
 *
 * - **KPI methods**: Each method retrieves KPI data for a specific category (sales, purchase, supplier, etc.)
 *   based on optional date range parameters provided as request parameters.
*/

package com.nebula.erp.reports.controller;

import com.nebula.erp.reports.documents.KPISwagger;
import com.nebula.erp.reports.service.*;
import com.nebula.erp.reports.utility.CreateLogger;
import com.nebula.erp.reports.utility.PermissionHelper;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.format.annotation.DateTimeFormat;
import com.nebula.erp.reports.utility.ApiResponseStructure;
import java.time.LocalDate;
import java.util.Map;

@RestController
@RequestMapping("/api/kpi")  // Base URI for KPI-related endpoints
@Tag(name="KPI Reports APIs", description = "APIs for managing KPI Display Reports")
@KPISwagger.GlobalErrorResponse
public class KPIController {

    @Autowired
    private SalesService salesService;

    @Autowired
    private PurchaseService purchaseService;

    @Autowired
    private SupplierService supplierService;

    @Autowired
    private TaxService taxService;
  
    @Autowired
    private PatientPrescriptionService patientPrescriptionService;

    @Autowired
    private FinancialService financialService;

    @Autowired
    private InventoryService inventoryService;

    @Autowired
    private AuditComplianceService auditComplianceService;


    @Autowired
    private RevenueService revenueService;

    @Autowired
    private PermissionHelper permissionHelper;

    @Autowired
    private CreateLogger createLogger;

    private static final String path = "/kpi";

    @KPISwagger.GetSalesKPIOperation
    @GetMapping("/sales")  // New endpoint for sales KPIs
    public ResponseEntity<ApiResponseStructure<Map<String, Object>>> getSalesKPI(
            @RequestParam(value = "start-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate,
            @RequestParam(value = "end-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) {

        // Check user permissions
        if (!permissionHelper.hasPermission("view-report")) {
            createLogger.createLogger("error", path, "GET", "Forbidden: You do not have the required permission. Please contact the administration.", "validation");
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ApiResponseStructure<>("error", HttpStatus.FORBIDDEN.value(), "Forbidden: You do not have the required permission. Please contact the administration.", null));
        }

        ApiResponseStructure<Map<String, Object>> response = salesService.getKPIData(fromDate, toDate);
        createLogger.createLogger("application", path, "GET", "Data retrieved.", "");
        return ResponseEntity.ok(response);
    }

    @KPISwagger.GetPurchaseKPIOperation
    @GetMapping("/purchase") // New endpoint for purchase KPIs
    public ResponseEntity<ApiResponseStructure<Map<String, Object>>> getPurchaseKPI(
            @RequestParam(value = "start-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate,
            @RequestParam(value = "end-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) {

        // Check user permissions
        if (!permissionHelper.hasPermission("view-report")) {
            createLogger.createLogger("error", path, "GET", "Forbidden: You do not have the required permission. Please contact the administration.", "validation");
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ApiResponseStructure<>("error", HttpStatus.FORBIDDEN.value(), "Forbidden: You do not have the required permission. Please contact the administration.", null));
        }

        ApiResponseStructure<Map<String, Object>> response = purchaseService.getKPIData(fromDate, toDate);
        createLogger.createLogger("application", path, "GET", "Data retrieved.", "");
        return ResponseEntity.ok(response);
    }

    @KPISwagger.GetSupplierKPIOperation
    @GetMapping("/supplier") // New endpoint for supplier KPIs
    public ResponseEntity<ApiResponseStructure<Map<String, Object>>> getSupplierKPI(
            @RequestParam(value = "start-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate,
            @RequestParam(value = "end-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) {

        // Check user permissions
        if (!permissionHelper.hasPermission("view-report")) {
            createLogger.createLogger("error", path, "GET", "Forbidden: You do not have the required permission. Please contact the administration.", "validation");
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ApiResponseStructure<>("error", HttpStatus.FORBIDDEN.value(), "Forbidden: You do not have the required permission. Please contact the administration.", null));
        }

        ApiResponseStructure<Map<String, Object>> response = supplierService.getKPIData(fromDate, toDate);
        createLogger.createLogger("application", path, "GET", "Data retrieved.", "");
        return ResponseEntity.ok(response);
    }

    @KPISwagger.GetTaxKPIOperation
    @GetMapping("/tax") // New endpoint for tax KPIs
    public ResponseEntity<ApiResponseStructure<Map<String, Object>>> getTaxKPI(
            @RequestParam(value = "start-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate,
            @RequestParam(value = "end-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) {

        // Check user permissions
        if (!permissionHelper.hasPermission("view-report")) {
            createLogger.createLogger("error", path, "GET", "Forbidden: You do not have the required permission. Please contact the administration.", "validation");
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ApiResponseStructure<>("error", HttpStatus.FORBIDDEN.value(), "Forbidden: You do not have the required permission. Please contact the administration.", null));
        }

        ApiResponseStructure<Map<String, Object>> response = taxService.getKPIData(fromDate, toDate);
        createLogger.createLogger("application", path, "GET", "Data retrieved.", "");
        return ResponseEntity.ok(response);
    }

    @KPISwagger.GetPatientPrescriptionKPIOperation
    @GetMapping("/patient-prescription") // New endpoint for supplier KPIs
    public ResponseEntity<ApiResponseStructure<Map<String, Object>>> getPatientPrescriptionKPI(
            @RequestParam(value = "start-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate,
            @RequestParam(value = "end-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) {

        // Check user permissions
        if (!permissionHelper.hasPermission("view-report")) {
            createLogger.createLogger("error", path, "GET", "Forbidden: You do not have the required permission. Please contact the administration.", "validation");
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ApiResponseStructure<>("error", HttpStatus.FORBIDDEN.value(), "Forbidden: You do not have the required permission. Please contact the administration.", null));
        }

        ApiResponseStructure<Map<String, Object>> response = patientPrescriptionService.getKPIData(fromDate, toDate);
        createLogger.createLogger("application", path, "GET", "Data retrieved.", "");
        return ResponseEntity.ok(response);
    }

    @KPISwagger.GetFinancialKPIOperation
    @GetMapping("/financial") // New endpoint for financial KPIs
    public ResponseEntity<ApiResponseStructure<Map<String, Object>>> getFinancialKPI(
            @RequestParam(value = "start-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate,
            @RequestParam(value = "end-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) {

        // Check user permissions
        if (!permissionHelper.hasPermission("view-report")) {
            createLogger.createLogger("error", path, "GET", "Forbidden: You do not have the required permission. Please contact the administration.", "validation");
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ApiResponseStructure<>("error", HttpStatus.FORBIDDEN.value(), "Forbidden: You do not have the required permission. Please contact the administration.", null));
        }

        ApiResponseStructure<Map<String, Object>> response = financialService.getKPIData(fromDate, toDate);
        createLogger.createLogger("application", path, "GET", "Data retrieved.", "");
        return ResponseEntity.ok(response);
    }

    @KPISwagger.GetInventoryKPIOperation
    @GetMapping("/inventory") // New endpoint for inventory KPIs
    public ResponseEntity<ApiResponseStructure<Map<String, Object>>> getInventoryKPI(
            @RequestParam(value = "start-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate,
            @RequestParam(value = "end-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) {

        // Check user permissions
        if (!permissionHelper.hasPermission("view-report")) {
            createLogger.createLogger("error", path, "GET", "Forbidden: You do not have the required permission. Please contact the administration.", "validation");
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ApiResponseStructure<>("error", HttpStatus.FORBIDDEN.value(), "Forbidden: You do not have the required permission. Please contact the administration.", null));
        }

        ApiResponseStructure<Map<String, Object>> response = inventoryService.getKPIData(fromDate, toDate);
        createLogger.createLogger("application", path, "GET", "Data retrieved.", "");
        return ResponseEntity.ok(response);
    }

    @KPISwagger.GetAuditComplianceKPIOperation
    @GetMapping("/audit-compliance") // New endpoint for inventory KPIs
    public ResponseEntity<ApiResponseStructure<Map<String, Object>>> getAuditComplianceKPI(
            @RequestParam(value = "start-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate,
            @RequestParam(value = "end-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) {

        // Check user permissions
        if (!permissionHelper.hasPermission("view-report")) {
            createLogger.createLogger("error", path, "GET", "Forbidden: You do not have the required permission. Please contact the administration.", "validation");
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ApiResponseStructure<>("error", HttpStatus.FORBIDDEN.value(), "Forbidden: You do not have the required permission. Please contact the administration.", null));
        }

        ApiResponseStructure<Map<String, Object>> response = auditComplianceService.getKPIData(fromDate, toDate);
        createLogger.createLogger("application", path, "GET", "Data retrieved.", "");
        return ResponseEntity.ok(response);
    }

    @KPISwagger.GetRevenueKPIOperation
    @GetMapping("/revenue") // New endpoint for inventory KPIs
    public ResponseEntity<ApiResponseStructure<Map<String, Object>>> getRevenueKPI(
            @RequestParam(value = "start-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate,
            @RequestParam(value = "end-date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) {

        // Check user permissions
        if (!permissionHelper.hasPermission("view-report")) {
            createLogger.createLogger("error", path, "GET", "Forbidden: You do not have the required permission. Please contact the administration.", "validation");
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ApiResponseStructure<>("error", HttpStatus.FORBIDDEN.value(), "Forbidden: You do not have the required permission. Please contact the administration.", null));
        }

        ApiResponseStructure<Map<String, Object>> response = revenueService.getKPIData(fromDate, toDate);
        createLogger.createLogger("application", path, "GET", "Data retrieved.", "");
        return ResponseEntity.ok(response);
    }

}