package com.utopiaindustries.qualitychecker.service;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;

import com.utopiaindustries.qualitychecker.db.ReportRepository;
import com.utopiaindustries.qualitychecker.models.InspectionReport;
import com.utopiaindustries.qualitychecker.models.InspectionReportWrapper;
import com.utopiaindustries.qualitychecker.models.callback.SaveReportCallback;
import com.utopiaindustries.qualitychecker.notification.NotificationHelper;
import com.utopiaindustries.qualitychecker.utils.FileUtils;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;

public class NetworkService extends Service {

    private static final String TAG = "NetworkService";

    @Override
    public void onCreate() {
        super.onCreate();
        // Start the connectivity check
        startCheckingNetwork();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Handle service start logic if needed
        return START_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void startCheckingNetwork() {
        Handler handler = new Handler();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                checkNetworkAndPushData();
                handler.postDelayed(this, 1 * 60 * 1000); // Check 5 every minute
            }
        };
        handler.post(runnable);
    }

    private void checkNetworkAndPushData() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null && activeNetwork.isConnected();

        if (isConnected) {
            Log.i(TAG, "Network is available. Pushing data...");
            // Call your method to push data here
            pushDataToInternet();
        } else {
            Log.i(TAG, "No network available.");
        }
    }

    @SuppressLint("DefaultLocale")
    private void pushDataToInternet() {
        ReportRepository repository = new ReportRepository( this );
        List<InspectionReportWrapper> reportWrappers = repository.findAllUnsynced();
        InspectionReportService service = InspectionReportService.getInstance();
        try {
            List<InspectionReport> reports = getReports( reportWrappers );
            int size = reports.size();
            if( size > 0 ){
                /*NotificationHelper.showNotification(
                        this,
                        "Uploading Reports",
                        String.format(" %d report(s) uploading..", reports.size() )
                );*/
                for ( InspectionReport report : reports ){
                    service.saveReport(report, new SaveReportCallback() {
                        @Override
                        public void onSuccess() {
                            // update status
                            repository.updateSyncStatus(  report.getWrapperId() );
                            // remove file
                            FileUtils.deleteFile( report.getFilePath() );

                            NotificationHelper.showNotification(
                                    NetworkService.this,
                                    "Report Status", "1 Report uploaded successfully");
                        }
                        @Override
                        public void onFailure(Throwable throwable) {

                        }
                    });
                }
                /*NotificationHelper.showNotification(
                        this,
                        "Uploading Reports",
                        String.format(" %d report(s) uploaded successfully..", reports.size() )
                );*/
            }
        } catch ( Exception e ) {
            e.printStackTrace();
        }
    }

    /*
    * map wrapper to reports
    * */
    private List<InspectionReport> getReports(List<InspectionReportWrapper> wrappers ) {
        List<InspectionReport> reports = new ArrayList<>();
        if( ! wrappers.isEmpty() ){
            for( InspectionReportWrapper wrapper : wrappers ){
                try {
                    // get file from path
                    byte[] result = FileUtils.readFile( wrapper.getContent() );
                    ByteArrayInputStream byteIn = new ByteArrayInputStream( result );
                    ObjectInputStream in = new ObjectInputStream(byteIn);
                    InspectionReport report = ( InspectionReport ) in.readObject();
                    report.setWrapperId( wrapper.getId() );
                    report.setFilePath( wrapper.getContent() );
                    reports.add( report );
                } catch ( Exception e){
                    e.printStackTrace();
                }
                catch (OutOfMemoryError e) {
                    e.printStackTrace();
                }
            }
        }
        return reports;
    }
}
