/*
 * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.micode.notes.ui;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

/**
 * 布局管理器控制类
 * <p>
 * 负责管理RecyclerView的布局切换，提供平滑的布局过渡效果。
 * 支持线性布局、网格布局和瀑布流布局的无缝切换。
 * 保存用户的布局偏好设置，确保应用重启后保持布局状态。
 * </p>
 */
public class LayoutManagerController {
    private static final String TAG = "LayoutManagerController";
    private static final String PREF_LAYOUT_TYPE = "layout_type";
    private static final String PREF_GRID_SPAN_COUNT = "grid_span_count";
    private static final String PREF_ITEM_SPACING = "item_spacing";

    private Context mContext;
    private RecyclerView mRecyclerView;
    private RecyclerView.LayoutManager mCurrentLayoutManager;
    private LayoutType mCurrentLayoutType;
    private SharedPreferences mPreferences;
    private LayoutChangeListener mListener;

    /**
     * 布局变化监听器接口
     */
    public interface LayoutChangeListener {
        void onLayoutChanged(LayoutType newLayoutType);
        void onLayoutChangeFailed(Exception e);
    }

    /**
     * 构造函数
     * @param context 上下文
     * @param recyclerView RecyclerView实例
     * @param listener 布局变化监听器
     */
    public LayoutManagerController(Context context, RecyclerView recyclerView, LayoutChangeListener listener) {
        mContext = context;
        mRecyclerView = recyclerView;
        mListener = listener;
        mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        
        // 加载保存的布局类型
        String savedLayoutKey = mPreferences.getString(PREF_LAYOUT_TYPE, LayoutType.LINEAR.getKey());
        mCurrentLayoutType = LayoutType.fromKey(savedLayoutKey);
        
        Log.d(TAG, "LayoutManagerController initialized with layout: " + mCurrentLayoutType.getDisplayName());
    }

    /**
     * 初始化布局
     */
    public void initializeLayout() {
        switchLayout(mCurrentLayoutType, false);
    }

    /**
     * 切换布局
     * @param layoutType 目标布局类型
     * @param animate 是否播放动画
     * @return 切换是否成功
     */
    public boolean switchLayout(LayoutType layoutType, boolean animate) {
        if (layoutType == mCurrentLayoutType) {
            Log.d(TAG, "Already in " + layoutType.getDisplayName() + " mode");
            return true;
        }

        long startTime = System.currentTimeMillis();
        
        try {
            // 保存滚动位置
            int scrollPosition = 0;
            if (mRecyclerView.getLayoutManager() != null) {
                if (mRecyclerView.getLayoutManager() instanceof LinearLayoutManager) {
                    LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
                    scrollPosition = layoutManager.findFirstVisibleItemPosition();
                } else if (mRecyclerView.getLayoutManager() instanceof GridLayoutManager) {
                    GridLayoutManager layoutManager = (GridLayoutManager) mRecyclerView.getLayoutManager();
                    scrollPosition = layoutManager.findFirstVisibleItemPosition();
                } else if (mRecyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager) {
                    StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) mRecyclerView.getLayoutManager();
                    int[] positions = layoutManager.findFirstVisibleItemPositions(null);
                    scrollPosition = positions.length > 0 ? positions[0] : 0;
                }
            }

            // 移除所有装饰
            int decorationCount = mRecyclerView.getItemDecorationCount();
            for (int i = decorationCount - 1; i >= 0; i--) {
                mRecyclerView.removeItemDecorationAt(i);
            }

            // 创建新的布局管理器
            RecyclerView.LayoutManager newLayoutManager = createLayoutManager(layoutType);
            
            // 应用新布局
            if (animate) {
                mRecyclerView.setLayoutManager(newLayoutManager);
            } else {
                mRecyclerView.setLayoutManager(newLayoutManager);
            }

            // 添加间距装饰
            addItemDecoration(layoutType);

            // 保存布局偏好
            saveLayoutPreference(layoutType);

            // 恢复滚动位置
            restoreScrollPosition(scrollPosition);

            mCurrentLayoutManager = newLayoutManager;
            mCurrentLayoutType = layoutType;

            long duration = System.currentTimeMillis() - startTime;
            Log.d(TAG, "Layout switched to " + layoutType.getDisplayName() + " in " + duration + "ms");

            // 通知监听器
            if (mListener != null) {
                mListener.onLayoutChanged(layoutType);
            }

            return true;

        } catch (Exception e) {
            Log.e(TAG, "Failed to switch layout: " + e.getMessage(), e);
            
            // 通知监听器失败
            if (mListener != null) {
                mListener.onLayoutChangeFailed(e);
            }
            
            return false;
        }
    }

    /**
     * 创建布局管理器
     * @param layoutType 布局类型
     * @return 布局管理器实例
     */
    private RecyclerView.LayoutManager createLayoutManager(LayoutType layoutType) {
        int spanCount = getGridSpanCount();
        switch (layoutType) {
            case LINEAR:
                return new LinearLayoutManager(mContext);
            case GRID:
                return new GridLayoutManager(mContext, spanCount);
            case STAGGERED:
                return new StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.VERTICAL);
            default:
                return new LinearLayoutManager(mContext);
        }
    }

    /**
     * 添加间距装饰
     * @param layoutType 布局类型
     */
    private void addItemDecoration(LayoutType layoutType) {
        int spacing = getItemSpacing();
        
        switch (layoutType) {
            case LINEAR:
                mRecyclerView.addItemDecoration(new NoteItemDecoration(mContext));
                break;
            case GRID:
                mRecyclerView.addItemDecoration(new GridSpacingItemDecoration(getGridSpanCount(), spacing, true));
                break;
            case STAGGERED:
                mRecyclerView.addItemDecoration(new StaggeredGridSpacingItemDecoration(getGridSpanCount(), spacing, true));
                break;
        }
    }

    /**
     * 恢复滚动位置
     * @param position 滚动位置
     */
    private void restoreScrollPosition(int position) {
        if (mRecyclerView.getAdapter() != null && position >= 0 && position < mRecyclerView.getAdapter().getItemCount()) {
            mRecyclerView.scrollToPosition(position);
        }
    }

    /**
     * 保存布局偏好
     * @param layoutType 布局类型
     */
    private void saveLayoutPreference(LayoutType layoutType) {
        mPreferences.edit()
                .putString(PREF_LAYOUT_TYPE, layoutType.getKey())
                .apply();
    }

    /**
     * 获取网格列数
     * @return 网格列数
     */
    public int getGridSpanCount() {
        return mPreferences.getInt(PREF_GRID_SPAN_COUNT, 2);
    }

    /**
     * 设置网格列数
     * @param spanCount 网格列数
     */
    public void setGridSpanCount(int spanCount) {
        if (spanCount < 1) spanCount = 1;
        if (spanCount > 4) spanCount = 4;
        
        mPreferences.edit()
                .putInt(PREF_GRID_SPAN_COUNT, spanCount)
                .apply();
        
        // 重新应用布局
        switchLayout(mCurrentLayoutType, true);
    }

    /**
     * 获取项目间距
     * @return 项目间距（像素）
     */
    public int getItemSpacing() {
        return mPreferences.getInt(PREF_ITEM_SPACING, 16);
    }

    /**
     * 设置项目间距
     * @param spacing 项目间距（像素）
     */
    public void setItemSpacing(int spacing) {
        if (spacing < 0) spacing = 0;
        if (spacing > 48) spacing = 48;
        
        mPreferences.edit()
                .putInt(PREF_ITEM_SPACING, spacing)
                .apply();
        
        // 重新应用布局
        switchLayout(mCurrentLayoutType, true);
    }

    /**
     * 获取当前布局类型
     * @return 当前布局类型
     */
    public LayoutType getCurrentLayoutType() {
        return mCurrentLayoutType;
    }

    /**
     * 获取下一个布局类型（循环切换）
     * @return 下一个布局类型
     */
    public LayoutType getNextLayoutType() {
        LayoutType[] types = LayoutType.values();
        int currentIndex = 0;
        for (int i = 0; i < types.length; i++) {
            if (types[i] == mCurrentLayoutType) {
                currentIndex = i;
                break;
            }
        }
        return types[(currentIndex + 1) % types.length];
    }
}
