<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;

use App\Models\ReportsModel;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;

class ReportsController extends BaseController
{
    protected $reportsModel;

    public function __construct()
    {
        // Load any necessary models or libraries here
        $this->reportsModel = new ReportsModel();
    }

    public function index()
    {
        //
    }

    public function advancePurchaseReport()
    {
        try {
            $data = $this->request->getJSON(true);

            $fromDate = $data['fromDate'] ?? '';
            $toDate   = $data['toDate'] ?? '';

            $result = $this->reportsModel->advancePurchaseReport($fromDate, $toDate);

            if (empty($result)) {
                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'No data found for the given criteria.'
                ])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
            }

            // Separate domestic
            $domestic = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'Domestic'));

            // Separate international
            $international = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'International'));

            if(isset($data['export']))
            {
                if($data['export'] == 'domestic'){ $exportData = $domestic; }else{ $exportData = $international;  }

                if(count($exportData) == 0){  return $this->response->setJSON(['status'  => 'failed','message' => 'No Data','data'    => [ ]]); }

                return $this->downloadExcel($exportData);
            }

            return $this->response->setJSON([
                'status'  => 'success',
                'message' => 'Data found for the given criteria.',
                'data'    => [
                    'domestic'     => $domestic,
                    'international' => $international
                ]
            ])->setStatusCode(ResponseInterface::HTTP_OK);

        } catch (\Throwable $th) {
            log_message('error', 'advancePurchaseReport Exception: ' . $th->getMessage());

                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'Something went wrong while processing the request.'
                ])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);

        } finally {
            
        }
    }


    public function misServicesAnalysis()
    {
        try {
            $data = $this->request->getJSON(true);

            $fromDate  = $data['fromDate']  ?? '';
            $toDate    = $data['toDate']    ?? '';

            $result = $this->reportsModel->misServicesAnalysis( $fromDate, $toDate);


            if (empty($result)) {
                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'No data found for the given criteria.'
                ])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
            }

            // Flatten the array
            $flat_result = [];

            foreach ($result as $group) {
                foreach ($group as $row) {
                    $flat_result[] = $row;
                }
            }

            // Separate domestic
            $domestic = array_values(array_filter($flat_result, fn($row) => $row['plan_trip_type'] === 'Domestic'));

            // Separate international
            $international = array_values(array_filter($flat_result, fn($row) => $row['plan_trip_type'] === 'International'));



                if(isset($data['export']))
                {
                    if($data['export'] == 'domestic'){ $exportData = $domestic; }else{ $exportData = $international;  }

                    if(count($exportData) == 0){  return $this->response->setJSON(['status'  => 'failed','message' => 'No Data','data'    => [ ]]); }

                    return $this->downloadExcel($exportData);
                }

                return $this->response->setJSON([
                    'status'  => 'success',
                    'message' => 'Data found for the given criteria.',
                    'data'    => [
                        'domestic'     => $domestic,
                        'international' => $international
                    ]
                ])->setStatusCode(ResponseInterface::HTTP_OK);


        } catch (\Throwable $th) {
            log_message('error', 'misServicesAnalysis Exception: ' . $th->getMessage());

                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'Something went wrong while processing the request.'
                ])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);

        } finally {

        }
    }


    public function misAirReport()
    {

        try {
            $data = $this->request->getJSON(true);

            $fromDate = $data['fromDate'] ?? '';
            $toDate   = $data['toDate'] ?? '';

            $result = $this->reportsModel->misAirReport($fromDate, $toDate);

            if (empty($result)) {
                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'No data found for the given criteria.'
                ])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
            }

            // Separate domestic
            $domestic = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'Domestic'));

            // Separate international
            $international = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'International'));

            if(isset($data['export']))
            {
                if($data['export'] == 'domestic'){ $exportData = $domestic; }else{ $exportData = $international;  }

                if(count($exportData) == 0){  return $this->response->setJSON(['status'  => 'failed','message' => 'No Data','data'    => [ ]]); }

                return $this->downloadExcel($exportData);
            }

            return $this->response->setJSON([
                'status'  => 'success',
                'message' => 'Data found for the given criteria.',
                'data'    => [
                    'domestic'     => $domestic,
                    'international' => $international
                ]
            ])->setStatusCode(ResponseInterface::HTTP_OK);

        } catch (\Throwable $th) {
            log_message('error', 'misAirReport Exception: ' . $th->getMessage());

                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'Something went wrong while processing the request.'
                ])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);

        } finally {
            
        }
    }

    public function misHotelReport()
    {

        try {
            $data = $this->request->getJSON(true);

            $fromDate = $data['fromDate'] ?? '';
            $toDate   = $data['toDate'] ?? '';

            $result = $this->reportsModel->misHotelReport($fromDate, $toDate);

            if (empty($result)) {
                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'No data found for the given criteria.'
                ])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
            }

            // Separate domestic
            $domestic = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'Domestic'));

            // Separate international
            $international = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'International'));


            if(isset($data['export']))
            {
                if($data['export'] == 'domestic'){ $exportData = $domestic; }else{ $exportData = $international;  }

                if(count($exportData) == 0){  return $this->response->setJSON(['status'  => 'failed','message' => 'No Data','data'    => [ ]]); }

                return $this->downloadExcel($exportData);
            }

            
            return $this->response->setJSON([
                'status'  => 'success',
                'message' => 'Data found for the given criteria.',
                'data'    => [
                    'domestic'     => $domestic,
                    'international' => $international
                ]
            ])->setStatusCode(ResponseInterface::HTTP_OK);

        } catch (\Throwable $th) {
            log_message('error', 'misAirReport Exception: ' . $th->getMessage());

                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'Something went wrong while processing the request.'
                ])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);

        } finally {
            
        }
    }

    public function misForexReport()
    {

        try {
            $data = $this->request->getJSON(true);

            $fromDate = $data['fromDate'] ?? '';
            $toDate   = $data['toDate'] ?? '';

            $result = $this->reportsModel->misForexReport($fromDate, $toDate);

            if (empty($result)) {
                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'No data found for the given criteria.'
                ])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
            }

            if(isset($data['export']))
            {
                if(count($result) == 0){  return $this->response->setJSON(['status'  => 'failed','message' => 'No Data','data'    => [ ]]); }

                return $this->downloadExcel($result);
            }


            return $this->response->setJSON([
                'status'  => 'success',
                'message' => 'Data found for the given criteria.',
                'data'    => $result
            ])->setStatusCode(ResponseInterface::HTTP_OK);

        } catch (\Throwable $th) {
            log_message('error', 'misAirReport Exception: ' . $th->getMessage());

                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'Something went wrong while processing the request.'
                ])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);

        } finally {
            
        }
    }

    public function guestHouseReport()
    {

        try {
            $data = $this->request->getJSON(true);

            $fromDate = $data['fromDate'] ?? '';
            $toDate   = $data['toDate'] ?? '';

            $result = $this->reportsModel->guestHouseReport($fromDate, $toDate);

            if (empty($result)) {
                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'No data found for the given criteria.'
                ])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
            }

            // Separate domestic
            $domestic = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'Domestic'));

            // Separate international
            $international = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'International'));

            if(isset($data['export']))
            {
                if($data['export'] == 'domestic'){ $exportData = $domestic; }else{ $exportData = $international;  }

                if(count($exportData) == 0){  return $this->response->setJSON(['status'  => 'failed','message' => 'No Data','data'    => [ ]]); }

                return $this->downloadExcel($exportData);
            }

            return $this->response->setJSON([
                'status'  => 'success',
                'message' => 'Data found for the given criteria.',
                'data'    => [
                    'domestic'     => $domestic,
                    'international' => $international
                ]
            ])->setStatusCode(ResponseInterface::HTTP_OK);

        } catch (\Throwable $th) {
            log_message('error', 'misAirReport Exception: ' . $th->getMessage());

                return $this->response->setJSON([
                    'status'  => 'error',
                    'message' => 'Something went wrong while processing the request.'
                ])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);

        } finally {
            
        }
    }


    //excel download
    public function downloadExcel($data)
    {
       
        if (empty($data) || !is_array($data)) {
            return 'No valid data provided.';
        }

        // Create Spreadsheet
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        // Generate headers from the first row
        $headers = array_keys($data[0]);
        $col = 'A';

        foreach ($headers as $header) {
            $sheet->setCellValue($col . '1', $header);
            $col++;
        }

        // Fill data
        $rowNum = 2;
        foreach ($data as $row) {
            $col = 'A';
            foreach ($headers as $header) {
                $sheet->setCellValue($col . $rowNum, $row[$header]);
                $col++;
            }
            $rowNum++;
        }

        // Write to output
        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');

        // Set headers for download
        $filename = 'dynamic_excel_' . date('YmdHis') . '.xlsx';

        return $this->response
            ->setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            ->setHeader('Content-Disposition', "attachment;filename=\"$filename\"")
            ->setHeader('Cache-Control', 'max-age=0')
            ->setBody($this->writeToTempFile($writer));
    }

    private function writeToTempFile($writer): string
    {
        $temp_file = tempnam(sys_get_temp_dir(), 'excel_') . '.xlsx';
        $writer->save($temp_file);
        return file_get_contents($temp_file);
    }



}
