package com.xyoye.dandanplay.mvp.impl;

import android.arch.lifecycle.LifecycleOwner;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;

import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.StringUtils;
import com.xyoye.dandanplay.app.IApplication;
import com.xyoye.dandanplay.base.BaseMvpPresenterImpl;
import com.xyoye.dandanplay.bean.FolderBean;
import com.xyoye.dandanplay.bean.VideoBean;
import com.xyoye.dandanplay.bean.event.UpdateFolderDanmuEvent;
import com.xyoye.dandanplay.mvp.presenter.PlayFragmentPresenter;
import com.xyoye.dandanplay.mvp.view.PlayFragmentView;
import com.xyoye.dandanplay.ui.activities.play.PlayerManagerActivity;
import com.xyoye.dandanplay.utils.CommonUtils;
import com.xyoye.dandanplay.utils.Constants;
import com.xyoye.dandanplay.utils.database.DataBaseInfo;
import com.xyoye.dandanplay.utils.database.DataBaseManager;
import com.xyoye.dandanplay.utils.database.callback.QueryAsyncResultCallback;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by xyoye on 2018/6/29.
 */

public class PlayFragmentPresenterImpl extends BaseMvpPresenterImpl<PlayFragmentView> implements PlayFragmentPresenter {

    public PlayFragmentPresenterImpl(PlayFragmentView view, LifecycleOwner lifecycleOwner) {
        super(view, lifecycleOwner);
    }

    @Override
    public void init() {

    }

    @Override
    public void process(Bundle savedInstanceState) {

    }

    @Override
    public void resume() {

    }

    @Override
    public void pause() {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void playLastVideo(Context context, String videoPath) {
        DataBaseManager.getInstance()
                .selectTable("file")
                .query()
                .queryColumns("danmu_path", "current_position", "danmu_episode_id", "zimu_path")
                .where("file_path", videoPath)
                .postExecute(new QueryAsyncResultCallback<VideoBean>(getLifecycle()) {
                    @Override
                    public VideoBean onQuery(Cursor cursor) {
                        if (cursor == null) return null;
                        VideoBean videoBean = null;
                        if (cursor.moveToNext()) {
                            videoBean = new VideoBean();
                            videoBean.setVideoPath(videoPath);
                            videoBean.setDanmuPath(cursor.getString(0));
                            videoBean.setCurrentPosition(cursor.getInt(1));
                            videoBean.setEpisodeId(cursor.getInt(2));
                            videoBean.setZimuPath(cursor.getString(3));
                        }
                        return videoBean;
                    }

                    @Override
                    public void onResult(VideoBean videoBean) {
                        if (videoBean == null)
                            return;
                        //视频文件是否已被删除
                        File videoFile = new File(videoBean.getVideoPath());
                        if (!videoFile.exists())
                            return;
                        //弹幕文件是否已被删除
                        if (!StringUtils.isEmpty(videoBean.getDanmuPath())) {
                            File danmuFile = new File(videoBean.getDanmuPath());
                            if (!danmuFile.exists())
                                videoBean.setDanmuPath("");
                        }
                        //字幕幕文件是否已被删除
                        if (!StringUtils.isEmpty(videoBean.getZimuPath())) {
                            File zimuFile = new File(videoBean.getZimuPath());
                            if (!zimuFile.exists())
                                videoBean.setZimuPath("");
                        }

                        PlayerManagerActivity.launchPlayerLocal(
                                context,
                                FileUtils.getFileNameNoExtension(videoBean.getVideoPath()),
                                videoBean.getVideoPath(),
                                videoBean.getDanmuPath(),
                                videoBean.getZimuPath(),
                                videoBean.getCurrentPosition(),
                                videoBean.getEpisodeId());
                    }
                });
    }

    /**
     * 刷新视频文件
     *
     * @param reScan true: 重新扫描整个系统目录
     *               false: 只查询数据库数据
     */
    @Override
    public void refreshVideo(Context context, boolean reScan) {
        //通知系统刷新目录
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
        if (context != null)
            context.sendBroadcast(intent);

        if (reScan) {
            refreshAllVideo();
        } else {
            refreshDatabaseVideo();
        }

        EventBus.getDefault().post(new UpdateFolderDanmuEvent());
    }

    @Override
    public void filterFolder(String folderPath) {
        DataBaseManager.getInstance()
                .selectTable("scan_folder")
                .insert()
                .param("folder_path", folderPath)
                .param("folder_type", Constants.ScanType.BLOCK)
                .postExecute();
    }

    @Override
    public void deleteFolderVideo(String folderPath) {
        File folder = new File(folderPath);
        if (folder.exists() && folder.isDirectory()) {
            for (File file : folder.listFiles()) {
                if (CommonUtils.isMediaFile(file.getAbsolutePath())) {
                    file.delete();
                }
            }
        }
        getView().deleteFolderSuccess();
    }

    /**
     * 扫描所有文件,更新数据库,刷新界面数据
     */
    private void refreshAllVideo() {
        //获取需要扫描的目录
        DataBaseManager.getInstance()
                .selectTable("scan_folder")
                .query()
                .queryColumns("folder_path")
                .where("folder_type", String.valueOf(Constants.ScanType.SCAN))
                .postExecute(new QueryAsyncResultCallback<List<FolderBean>>(getLifecycle()) {
                    @Override
                    public List<FolderBean> onQuery(Cursor cursor) {
                        if (cursor == null)
                            return new ArrayList<>();
                        List<String> scanFolderList = new ArrayList<>();
                        while (cursor.moveToNext()) {
                            scanFolderList.add(cursor.getString(0));
                        }

                        //是否获取系统中视频信息
                        boolean isScanMediaStore = scanFolderList.remove(Constants.DefaultConfig.SYSTEM_VIDEO_PATH);
                        if (isScanMediaStore) {
                            queryVideoFormMediaStore();
                        }

                        //遍历需要扫描的目录
                        queryVideoFormStorage(scanFolderList);

                        return DataBaseManager.getInstance()
                                .selectTable("scan_folder")
                                .query()
                                .queryColumns("folder_path", "folder_type")
                                .executeAsync(scanTypeCursor -> {
                                    if (scanTypeCursor == null)
                                        return new ArrayList<>();

                                    List<String> scanList = new ArrayList<>();
                                    List<String> blockList = new ArrayList<>();

                                    while (scanTypeCursor.moveToNext()) {
                                        if (Constants.ScanType.SCAN == scanTypeCursor.getInt(1)) {
                                            scanList.add(scanTypeCursor.getString(0));
                                        } else {
                                            blockList.add(scanTypeCursor.getString(0));
                                        }
                                    }
                                    return getVideoFormDatabase(scanList, blockList);
                                });
                    }

                    @Override
                    public void onResult(List<FolderBean> result) {
                        getView().refreshAdapter(result);
                    }
                });
    }

    /**
     * 仅根据数据库数据刷新界面
     */
    private void refreshDatabaseVideo() {
        DataBaseManager.getInstance()
                .selectTable("scan_folder")
                .query()
                .queryColumns("folder_path", "folder_type")
                .postExecute(new QueryAsyncResultCallback<List<FolderBean>>(getLifecycle()) {

                    @Override
                    public List<FolderBean> onQuery(Cursor cursor) {
                        if (cursor == null)
                            return new ArrayList<>();
                        List<String> scanList = new ArrayList<>();
                        List<String> blockList = new ArrayList<>();

                        while (cursor.moveToNext()) {
                            if (Constants.ScanType.SCAN == cursor.getInt(1)) {
                                scanList.add(cursor.getString(0));
                            } else {
                                blockList.add(cursor.getString(0));
                            }
                        }
                        return getVideoFormDatabase(scanList, blockList);
                    }

                    @Override
                    public void onResult(List<FolderBean> result) {
                        getView().refreshAdapter(result);
                    }
                });
    }

    /**
     * 从数据库中读取文件夹目录,过滤屏蔽目录及不扫描目录
     */
    private List<FolderBean> getVideoFormDatabase(List<String> scanList, List<String> blockList) {
        List<FolderBean> folderBeanList = new ArrayList<>();
        Map<String, Integer> beanMap = new HashMap<>();
        Map<String, String> deleteMap = new HashMap<>();

        //查询所有视频
        DataBaseManager.getInstance()
                .selectTable("file")
                .query()
                .queryColumns("folder_path", "file_path")
                .executeAsync(cursor -> {
                    while (cursor.moveToNext()) {
                        String folderPath = cursor.getString(0);
                        String filePath = cursor.getString(1);

                        //过滤屏蔽目录
                        boolean isBlock = false;
                        for (String blockPath : blockList) {
                            //视频属于屏蔽目录下视频,过滤
                            if (filePath.startsWith(blockPath)) {
                                isBlock = true;
                                break;
                            }
                        }
                        if (isBlock) continue;

                        //过滤非扫描目录,扫描包括系统目录时不用过滤
                        if (!scanList.contains(Constants.DefaultConfig.SYSTEM_VIDEO_PATH)) {
                            boolean isNotScan = true;
                            for (String scanPath : scanList) {
                                if (filePath.startsWith(scanPath)) {
                                    isNotScan = false;
                                    break;
                                }
                            }
                            if (isNotScan) continue;
                        }

                        //计算文件夹中文件数量
                        //文件不存在记录需要删除的文件
                        File file = new File(filePath);
                        if (file.exists()) {
                            if (beanMap.containsKey(folderPath)) {
                                Integer number = beanMap.get(folderPath);
                                number = number == null ? 0 : number;
                                beanMap.put(folderPath, ++number);
                            } else {
                                beanMap.put(folderPath, 1);
                            }
                        } else {
                            deleteMap.put(folderPath, filePath);
                        }
                    }
                });

        //更新文件夹文件数量
        for (Map.Entry<String, Integer> entry : beanMap.entrySet()) {
            folderBeanList.add(new FolderBean(entry.getKey(), entry.getValue()));
            DataBaseManager.getInstance()
                    .selectTable("folder")
                    .update()
                    .param("file_number", entry.getValue())
                    .where("folder_path", entry.getKey())
                    .executeAsync();
        }

        //删除不存在的文件
        for (Map.Entry<String, String> entry : deleteMap.entrySet()) {
            DataBaseManager.getInstance()
                    .selectTable("file")
                    .delete()
                    .where("folder_path", entry.getKey())
                    .where("file_path", entry.getValue())
                    .executeAsync();
        }
        return folderBeanList;
    }

    /**
     * 保存视频信息到数据库
     * 跳过已存在的视频信息
     */
    private void saveVideoToDatabase(VideoBean videoBean) {
        String folderPath = FileUtils.getDirName(videoBean.getVideoPath());
        ContentValues values = new ContentValues();
        values.put(DataBaseInfo.getFieldNames()[2][1], folderPath);
        values.put(DataBaseInfo.getFieldNames()[2][2], videoBean.getVideoPath());
        values.put(DataBaseInfo.getFieldNames()[2][5], String.valueOf(videoBean.getVideoDuration()));
        values.put(DataBaseInfo.getFieldNames()[2][7], String.valueOf(videoBean.getVideoSize()));
        values.put(DataBaseInfo.getFieldNames()[2][8], videoBean.get_id());

        DataBaseManager.getInstance()
                .selectTable("file")
                .query()
                .where("folder_path", folderPath)
                .where("file_path", videoBean.getVideoPath())
                .executeAsync(cursor -> {
                    if (!cursor.moveToNext()) {
                        DataBaseManager.getInstance()
                                .selectTable("file")
                                .insert()
                                .param("folder_path", folderPath)
                                .param("file_path", videoBean.getVideoPath())
                                .param("duration", String.valueOf(videoBean.getVideoDuration()))
                                .param("file_size", String.valueOf(videoBean.getVideoSize()))
                                .param("file_id", videoBean.get_id())
                                .executeAsync();
                    }
                });
    }

    /**
     * 获取系统中视频信息
     */
    private void queryVideoFormMediaStore() {
        Cursor cursor = IApplication.get_context().getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                null, null, null, null);
        if (cursor != null) {
            while (cursor.moveToNext()) {
                String path = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA));// 地址
                int _id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID));// id
                long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));// 大小
                long duration = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));// 时长

                VideoBean videoBean = new VideoBean();
                videoBean.set_id(_id);
                videoBean.setVideoPath(path);
                videoBean.setVideoDuration(duration);
                videoBean.setVideoSize(size);
                saveVideoToDatabase(videoBean);
            }
            cursor.close();
        }
    }

    /**
     * 遍历需要扫描的目录
     */
    private void queryVideoFormStorage(List<String> scanFolderList) {
        if (scanFolderList.size() == 0)
            return;
        File[] fileArray = new File[scanFolderList.size()];
        for (int i = 0; i < scanFolderList.size(); i++) {
            fileArray[i] = new File(scanFolderList.get(i));
        }
        for (File parentFile : fileArray) {
            for (File childFile : listFiles(parentFile)) {
                String filePath = childFile.getAbsolutePath();
                VideoBean videoBean = new VideoBean();
                videoBean.setVideoPath(filePath);
                videoBean.setVideoDuration(0);
                videoBean.setVideoSize(childFile.length());
                videoBean.set_id(0);
                saveVideoToDatabase(videoBean);
            }
        }
    }

    /**
     * 递归检查目录和文件
     */
    private List<File> listFiles(File file) {
        List<File> fileList = new ArrayList<>();
        if (file.isDirectory()) {
            File[] fileArray = file.listFiles();
            if (fileArray == null || fileArray.length == 0) {
                return new ArrayList<>();
            } else {
                for (File childFile : fileArray) {
                    if (childFile.isDirectory()) {
                        fileList.addAll(listFiles(childFile));
                    } else if (childFile.exists() && childFile.canRead() && CommonUtils.isMediaFile(childFile.getAbsolutePath())) {
                        fileList.add(childFile);
                    }
                }
            }
        } else if (file.exists() && file.canRead() && CommonUtils.isMediaFile(file.getAbsolutePath())) {
            fileList.add(file);
        }
        return fileList;
    }
}