package com.example.infiniteLoop.parkingo;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import androidx.annotation.NonNull;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import static android.content.ContentValues.TAG;

public class sqlite_ops extends SQLiteOpenHelper{
    FirebaseFirestore fdb;

    public static final int DATABASE_VERSION=1;
    public static final String DATABASE_NAME="parkingo.db";
    public sqlite_ops(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    public void onCreate(SQLiteDatabase db){
       // initFirebase();
        Log.d("Firebase","INside Oncreate sql");
        db.execSQL("create table admin(username varchar unique,password varchar)");
        db.execSQL("create table slots(id integer primary key autoincrement ,slot varchar unique,status int,category text)");
        db.execSQL("create table records(tkt_no integer  primary key autoincrement,name varchar,mobile int,slot varchar,vehicle varchar,check_in timestamp,check_out timestamp,isempty int)");
        db.execSQL("insert into admin values('shady','shady')");
        db.execSQL("insert into records values(10000,'Sample',100000000,'Sample','UP51SAMPLE',current_timestamp,null,1)");
        for(int i=0;i<5;i++){
            for(int j=0;j<15;j++){
                char s=(char)(i+65);
                String slot=Character.toString(s);
                if(j<10)
                    slot+="0";
                slot+=j;
                if(i<2)
                    //slotObj.put("category","BIKE");
                    db.execSQL("insert into slots values(null,'"+slot+"',0,'BIKE')");
                else
                    //slotObj.put("category","CAR");
                    db.execSQL("insert into slots values(null,'"+slot+"',0,'CAR')");
                //slotObj.put("slot",slot);

            }
        }

    }

    public void initFirebase() {
        //AddSlotsToFirebase();
        fdb = FirebaseFirestore.getInstance();
    }

    public void AddSlotsToFirebase() {
        Log.d("Firebase","Adding slots");
        Map<String, Object> slotObj = new HashMap<>();
        slotObj.put("status", 0);
        //city.put("state", "CA");
        //city.put("country", "USA");
        for(int i=0;i<5;i++){
            for(int j=0;j<15;j++){
                char s=(char)(i+65);
                String slot=Character.toString(s);
                if(j<10)
                    slot+="0";
                slot+=j;
                if(i<2)
                    slotObj.put("category","BIKE");
                    //db.execSQL("insert into slots values(null,'"+slot+"',0,'BIKE')");
                else
                    slotObj.put("category","CAR");
                //db.execSQL("insert into slots values(null,'"+slot+"',0,'CAR')");
                slotObj.put("slot",slot);
                fdb.collection("slots")
                        .add(slotObj)
                        .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                            @Override
                            public void onSuccess(DocumentReference docref) {
                                Log.d(TAG, "DocumentSnapshot successfully written!");
                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Log.w(TAG, "Error writing document", e);
                            }
                        });
            }
        }


    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

        sqLiteDatabase.execSQL("drop table if exists admin ; ");
        sqLiteDatabase.execSQL("drop table if exists slots;");
        sqLiteDatabase.execSQL("drop table if exists records;");

        onCreate(sqLiteDatabase);

    }


    public boolean fetch_login_details(final login li,final login_activity la){
      // SQLiteDatabase db= this.getReadableDatabase();
       /*
        //Log.d(TAG, "fetch_login_details: "+li.getUname()+" "+li.getPass());
        Cursor cursor = db.query("admin",new String[]{"username","password"},"username"+ "=?",
                new String[]{li.getUname()}, null, null, null, null);

        if (cursor != null) {
            cursor.moveToFirst();
            if(cursor.getCount()!=0){
            String pass = cursor.getString(cursor.getColumnIndex("password"));

            if (pass.equals(li.getPass())) {
                db.close();
                return true;

            } else {
                Log.d(TAG, "fetch_login_details: not equals "+pass);
                db.close();
                return false;
            }
            }
            else {
                db.close();
                return false;
            }
        }
        else {
            Log.d(TAG, "fetch_login_details: nothing selected");
            db.close();
            return false;
        }*/
        fdb = FirebaseFirestore.getInstance();
        Query query = fdb.collection("users").whereEqualTo("username",li.getUname());
        if(query!=null)
            query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if(task.isSuccessful()) {
                        QuerySnapshot documentSnapshot = task.getResult();
//                        Log.d("Firebase",documentSnapshot.);
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            if(document.getData().get("pass").toString().equals(li.getPass())){
                                la.loginSuccess(document.getData());
                                Log.d("Firebase",document.getData().get("pass").toString());
                            }
                            else
                                la.loginFailure();
                        }
                        if(documentSnapshot.isEmpty()) {
                            la.loginFailure();
                            Log.d("Login", "Failure");
                        }
                }else
                    Log.d("Login","Failure");
                }

        });
        return  true;
    }

    public boolean check_in(checkin_details cd){
        Long timeStamp = System.currentTimeMillis()/1000;

        Map<String, Object> parkingRecord = new HashMap<>();
        parkingRecord.put("name",cd.getName());
        parkingRecord.put("uname",userInfo.getInstance().getUsername());
        parkingRecord.put("mobile",cd.getMobile());
        parkingRecord.put("slot",cd.getSlot());
        parkingRecord.put("vehicle",cd.getVehicle_no());
        parkingRecord.put("checkInTimeDate",timeStamp.toString());
        parkingRecord.put("status",1);
        fdb = FirebaseFirestore.getInstance();
        fdb.collection("records")
                .add(parkingRecord)
                .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                    @Override
                    public void onSuccess(DocumentReference docref) {
                        Log.d(TAG, "Parking record successfully written!");
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.w(TAG, "Error writing document", e);
                    }
                });
        final CollectionReference collection=  fdb.collection("slots");
        fdb.collection("slots").whereEqualTo("slot",cd.getSlot()).get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if(task.isSuccessful()) {
                        QuerySnapshot documentSnapshot = task.getResult();
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            String id = document.getId();
                            collection.document(id).update("status", 1);
                        }
                    }
                    else {
                        Log.d("Checkin","slot update failed");
                    }
                }
            });
        return true;
    }

    public ArrayList getFreeSlots(final category_wise_availability cd, String category){

        String[] cat=new String[]{category.toUpperCase(),"0"};
        final ArrayList slots=new ArrayList();
        // SQLiteDatabase db= this.getWritableDatabase();
        // Cursor cursor = db.query("slots",new String[]{"slot"},"category=? and status=?",
        //         cat, null, null, null, null);
        // if(cursor!=null){
        //     cursor.moveToFirst();
        //     if(cursor.getCount()!=0){
        //     do{
        //         String data = cursor.getString(cursor.getColumnIndex("slot"));
        //         slots.add(data);
        //         // do what ever you want here
        //     }while(cursor.moveToNext());
        //     }

        // }
        // db.close();
        Log.d("Slots",slots.toString());
        fdb = FirebaseFirestore.getInstance();
        Query query = fdb.collection("slots").whereEqualTo("category",cat[0])
                .whereEqualTo("status",0);
        if(query!=null)
            query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if(task.isSuccessful()) {
                        QuerySnapshot documentSnapshot = task.getResult();
//                        Log.d("Firebase",documentSnapshot.);
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            Log.d(TAG, document.getId() + " => " + document.getData());
                            slots.add(document.getData().get("slot"));
                        }
                        if(documentSnapshot.isEmpty()) {
                           // la.loginFailure();
                            for (QueryDocumentSnapshot document : task.getResult()) {
                                Log.d(TAG, document.getId() + " => " + document.getData());
                            }
                            
                            Log.d("Login","Failure");
                        }else {
                           // la.loginSuccess();
                            Collections.sort(slots);
                            cd.returnSlots(slots);
                            Log.d("Login", "Success");
                        }
                    }else
                        Log.d("Login","Failure");
                }

            });
        Log.d("Slots",slots.toString());
        return slots;
    }
    public ArrayList getAllSlots(String category){
        String[] cat=new String[]{category.toUpperCase()};
        ArrayList slots=new ArrayList();
        SQLiteDatabase db= this.getWritableDatabase();
        Cursor cursor = db.query("slots",new String[]{"slot","status"},"category=?",
                cat, null, null, null, null);
        if(cursor!=null){
            cursor.moveToFirst();
            if(cursor.getCount()!=0){
                do{
                    HashMap hm=new HashMap();
                    hm.put("slot", cursor.getString(cursor.getColumnIndex("slot")));
                    hm.put("status",cursor.getString(cursor.getColumnIndex("status")));
                    slots.add(hm);
                    // do what ever you want here
                }while(cursor.moveToNext());
            }

        }
        db.close();
        return slots;
    }

    public ArrayList getTicketDetails(long ticket_no) {
        ArrayList al=new ArrayList();
        SQLiteDatabase db=this.getWritableDatabase();
        Cursor cr=db.query("records",new String []{"tkt_no","slot","vehicle","check_in","check_out"},"tkt_no=?",new String[]{Long.toString(ticket_no)},null,null,null,null);
        if(cr!=null){
            cr.moveToFirst();
            if(cr.getCount()>0){
                al.add(0,cr.getString(cr.getColumnIndex("tkt_no")));
                al.add(1,cr.getString(cr.getColumnIndex("slot")));
                al.add(2,cr.getString(cr.getColumnIndex("vehicle")));
                al.add(3,cr.getString(cr.getColumnIndex("check_in")));
                al.add(4,cr.getString(cr.getColumnIndex("check_out")));
            }
            else{
                al.add(0,ticket_no);
                al.add("");
                al.add("");
                al.add("");

            }

        }
        db.close();
        return al;
    }

    public  long lastIndexRecords(){
        SQLiteDatabase db=this.getReadableDatabase();
        Cursor c=db.query("records",new String[]{"tkt_no"},"",new String[]{},null,null,"tkt_no DESC","1");
        c.moveToFirst();
        Long res=Long.parseLong(c.getString(c.getColumnIndex("tkt_no")));
        db.close();
        return res;

    }

    public ArrayList fetch_ticket_detail(long ticket){
        ArrayList al=new ArrayList();
        SQLiteDatabase db=this.getWritableDatabase();
        Cursor cr=db.query("records",new 'String []{"name","mobile","tkt_no","slot","vehicle","check_in","isempty"},"tkt_no=?",new String[]{Long.toString(ticket)},null,null,null,null);
        if(cr!=null){
            cr.moveToFirst();
            if(cr.getCount()>0){
                al.add(0,cr.getString(cr.getColumnIndex("tkt_no")));
                al.add(1,cr.getString(cr.getColumnIndex("slot")));
                al.add(2,cr.getString(cr.getColumnIndex("vehicle")));
                al.add(3,cr.getString(cr.getColumnIndex("check_in")));
                al.add(4,cr.getString(cr.getColumnIndex("name")));
                al.add(5,cr.getString(cr.getColumnIndex("mobile")));
                al.add(6,cr.getString(cr.getColumnIndex("isempty")));


            }
            else{
                al.add(0,ticket);
                al.add("none");
                al.add("none");
                al.add("none");
                al.add("none");
                al.add("none");
                al.add("0");

            }

        }
        db.close();
        return al;
    }
    public void fetch_slot_details(String slot,final checkout co){
//        ArrayList al=new ArrayList();
//        SQLiteDatabase db=this.getWritableDatabase();
//        Cursor cr=db.query("records",new String []{"name","mobile","tkt_no","slot","vehicle","check_in","isempty"},"slot=? and isempty=?",new String[]{slot,"0"},null,null,null,null);
//        if(cr!=null){
//            cr.moveToFirst();
//            if(cr.getCount()>0){
//                al.add(0,cr.getString(cr.getColumnIndex("tkt_no")));
//                al.add(1,cr.getString(cr.getColumnIndex("slot")));
//                al.add(2,cr.getString(cr.getColumnIndex("vehicle")));
//                al.add(3,cr.getString(cr.getColumnIndex("check_in")));
//                al.add(4,cr.getString(cr.getColumnIndex("name")));
//                al.add(5,cr.getString(cr.getColumnIndex("mobile")));
//                al.add(6,cr.getString(cr.getColumnIndex("isempty")));
//
//
//            }
//            else{
//                al.add("none");
//                al.add("none");
//                al.add("none");
//                al.add("none");
//                al.add("none");
//                al.add("none");
//                al.add("0");
//
//            }
//
//        }
//        db.close();
        fdb = FirebaseFirestore.getInstance();
        fdb.collection("records").whereEqualTo("uname",userInfo.getInstance().getName())
                .whereEqualTo("status",1)
                .whereEqualTo("slot",slot).get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if(task.isSuccessful()) {
                            ArrayList al = new ArrayList();
                            for (QueryDocumentSnapshot document : task.getResult()) {
                                //  slots.add(document);
                               // ArrayList al = new ArrayList();
                                al.add(0,document.getId());
                                al.add(1,document.getData().get("slot"));
                                al.add(2,document.getData().get("vehicle"));
                                al.add(3,document.getData().get("checkInTimeDate"));
                                al.add(4,document.getData().get("name"));
                                al.add(5,document.getData().get("mobile"));
                                al.add(6,document.getData().get("status"));
                                Log.d("Ticket","getting slot ticket"+document.getData().toString());
                            }
                            co.showTicketDetails(al);
                            return;
                        }
                        else {
                            Log.d("Checkin","slot update failed");
                        }
                    }
                });

    }
    public boolean check_out(String slot,Long tkt){
        SQLiteDatabase db= this.getWritableDatabase();
        db.execSQL("update records set check_out=current_timestamp,isempty=1 where tkt_no="+tkt);
        db.execSQL("update slots set status=0 where slot='"+slot+"'");
        db.close();
        return true;
    }

    public void getAllFilledSlotDetails(final currentParks cp){
//        ArrayList slots=new ArrayList();
//        SQLiteDatabase db= this.getWritableDatabase();
//        Cursor cursor = db.query("records",new String[]{"name","mobile","vehicle","slot"},"isempty=?",
//                new String[]{"0"}, null, null, null, null);
//        if(cursor!=null){
//            cursor.moveToFirst();
//            if(cursor.getCount()!=0){
//                do{
//                    HashMap hm=new HashMap();
//                    hm.put("slot", cursor.getString(cursor.getColumnIndex("slot")));
//                    hm.put("vehicle",cursor.getString(cursor.getColumnIndex("vehicle")));
//                    hm.put("name",cursor.getString(cursor.getColumnIndex("name")));
//                    hm.put("mobile",cursor.getString(cursor.getColumnIndex("mobile")));
//                    slots.add(hm);
//                }while(cursor.moveToNext());
//            }
//
//        }
        fdb = FirebaseFirestore.getInstance();
        fdb.collection("records").whereEqualTo("uname",userInfo.getInstance().getName())
            .whereEqualTo("status",1).get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if(task.isSuccessful()) {
                        ArrayList slots = new ArrayList();
                        for (QueryDocumentSnapshot document : task.getResult()) {
                          //  slots.add(document);
                            HashMap hm = new HashMap();
                            hm.put("name",document.getData().get("name").toString());
                            hm.put("uname",document.getData().get("uname").toString());
                            hm.put("slot",document.getData().get("slot").toString());
                            hm.put("vehicle",document.getData().get("vehicle").toString());
                            hm.put("mobile",document.getData().get("mobile").toString());
                            Log.d("Ticket","getting record"+document.getData().toString());
                            slots.add(hm);
                        }
                        cp.showCurrentParkings(slots);
                    }
                    else {
                        Log.d("Checkin","slot update failed");
                    }
                }
            });
//        db.close();
        return;
    }
}