/*   This file is part of My Expenses.
 *   My Expenses is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   My Expenses is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with My Expenses.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.totschnig.myexpenses.dialog;


import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.squareup.picasso.Picasso;

import org.totschnig.myexpenses.R;
import org.totschnig.myexpenses.activity.ExpenseEdit;
import org.totschnig.myexpenses.activity.ProtectedFragmentActivity;
import org.totschnig.myexpenses.adapter.SplitPartAdapter;
import org.totschnig.myexpenses.model.Account;
import org.totschnig.myexpenses.model.Account.Type;
import org.totschnig.myexpenses.model.Money;
import org.totschnig.myexpenses.model.PaymentMethod;
import org.totschnig.myexpenses.model.Plan;
import org.totschnig.myexpenses.model.SplitTransaction;
import org.totschnig.myexpenses.model.Transaction;
import org.totschnig.myexpenses.model.Transfer;
import org.totschnig.myexpenses.provider.DbUtils;
import org.totschnig.myexpenses.provider.TransactionProvider;
import org.totschnig.myexpenses.task.TaskExecutionFragment;
import org.totschnig.myexpenses.ui.SimpleCursorAdapter;
import org.totschnig.myexpenses.util.Utils;

import java.io.File;
import java.text.DateFormat;

import static org.totschnig.myexpenses.provider.DatabaseConstants.KEY_AMOUNT;
import static org.totschnig.myexpenses.provider.DatabaseConstants.KEY_LABEL_MAIN;
import static org.totschnig.myexpenses.provider.DatabaseConstants.KEY_ROWID;

public class TransactionDetailFragment extends CommitSafeDialogFragment implements LoaderManager.LoaderCallbacks<Cursor>, OnClickListener {
  public static final int SPLIT_PART_CURSOR = 3;
  Transaction mTransaction;
  SimpleCursorAdapter mAdapter;
  View mLayout;

  public static final TransactionDetailFragment newInstance(Long id) {
    TransactionDetailFragment dialogFragment = new TransactionDetailFragment();
    Bundle bundle = new Bundle();
    bundle.putLong(KEY_ROWID, id);
    dialogFragment.setArguments(bundle);
    return dialogFragment;
  }

  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);
    ((ProtectedFragmentActivity) activity).startTaskExecution(
        TaskExecutionFragment.TASK_INSTANTIATE_TRANSACTION_2,
        new Long[]{getArguments().getLong(KEY_ROWID)},
        null,
        0);
  }

  @Override
  public Dialog onCreateDialog(Bundle savedInstanceState) {

    final LayoutInflater li = LayoutInflater.from(getActivity());
    //noinspection InflateParams
    mLayout = li.inflate(R.layout.transaction_detail, null);
    AlertDialog dialog = new AlertDialog.Builder(getActivity())
        .setTitle(R.string.progress_dialog_loading)
        //.setIcon(android.R.color.transparent)
        .setView(mLayout)
        .setNegativeButton(android.R.string.ok, this)
        .setPositiveButton(R.string.menu_edit, this)
        .setNeutralButton(R.string.menu_view_picture, this)
        .create();
    dialog.setOnShowListener(new ButtonOnShowDisabler() {
      @Override
      public void onShow(DialogInterface dialog) {
        if (mTransaction == null) {
          super.onShow(dialog);
          Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_NEUTRAL);
          if (button != null) {
            button.setVisibility(View.GONE);
          }
        }
      }
    });
    return dialog;
  }

  @Override
  public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
    if (getActivity() == null) {
      return null;
    }
    switch (id) {
      case SPLIT_PART_CURSOR:
        CursorLoader cursorLoader = new CursorLoader(getActivity(), TransactionProvider.TRANSACTIONS_URI, null, "parent_id = ?",
            new String[]{String.valueOf(mTransaction.getId())}, null);
        return cursorLoader;
    }
    return null;
  }

  @Override
  public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    int id = loader.getId();
    switch (id) {
      case SPLIT_PART_CURSOR:
        mAdapter.swapCursor(cursor);
    }
  }

  @Override
  public void onLoaderReset(Loader<Cursor> loader) {
    mAdapter.swapCursor(null);
  }

  @Override
  public void onClick(DialogInterface dialog, int which) {
    Activity ctx = getActivity();
    if (ctx == null || mTransaction == null) {
      return;
    }
    switch (which) {
      case AlertDialog.BUTTON_POSITIVE:
        if (mTransaction.transfer_peer != null && DbUtils.hasParent(mTransaction.transfer_peer)) {
          Toast.makeText(ctx, getString(R.string.warning_splitpartcategory_context), Toast.LENGTH_LONG).show();
          return;
        }
        Intent i = new Intent(ctx, ExpenseEdit.class);
        i.putExtra(KEY_ROWID, mTransaction.getId());
        //i.putExtra("operationType", operationType);
        ctx.startActivityForResult(i, ProtectedFragmentActivity.EDIT_TRANSACTION_REQUEST);
        break;
      case AlertDialog.BUTTON_NEUTRAL:
        startActivity(Transaction.getViewIntent(mTransaction.getPictureUri()));
        break;
      case AlertDialog.BUTTON_NEGATIVE:
        dismiss();
    }
  }

  public void fillData(Transaction o) {
    final FragmentActivity ctx = getActivity();
    mLayout.findViewById(R.id.progress).setVisibility(View.GONE);
    mTransaction = o;
    if (mTransaction == null) {
      TextView error = (TextView) mLayout.findViewById(R.id.error);
      error.setVisibility(View.VISIBLE);
      error.setText(R.string.transaction_deleted);
      return;
    }
    boolean doShowPicture = false;
    if (mTransaction.getPictureUri() != null) {
      doShowPicture = true;
      if (mTransaction.getPictureUri().getScheme().equals("file")) {
        if (!new File(mTransaction.getPictureUri().getPath()).exists()) {
          Toast.makeText(getActivity(), R.string.image_deleted, Toast.LENGTH_SHORT).show();
          doShowPicture = false;
        }
      }
    }
    AlertDialog dlg = (AlertDialog) getDialog();
    if (dlg != null) {
      Button btn = dlg.getButton(AlertDialog.BUTTON_POSITIVE);
      if (btn != null) {
        if (mTransaction.crStatus != Transaction.CrStatus.VOID) {
          btn.setEnabled(true);
        } else {
          btn.setVisibility(View.GONE);
        }
      }
      btn = dlg.getButton(AlertDialog.BUTTON_NEUTRAL);
      if (btn != null) {
        btn.setVisibility(doShowPicture ? View.VISIBLE : View.GONE);
      }
    }
    mLayout.findViewById(R.id.Table).setVisibility(View.VISIBLE);
    int title;
    boolean type = mTransaction.getAmount().getAmountMinor() > 0 ? ExpenseEdit.INCOME : ExpenseEdit.EXPENSE;

    if (mTransaction instanceof SplitTransaction) {
      mLayout.findViewById(R.id.SplitContainer).setVisibility(View.VISIBLE);
      //TODO: refactor duplicated code with SplitPartList
      title = R.string.split_transaction;
      View emptyView = mLayout.findViewById(R.id.empty);

      ListView lv = (ListView) mLayout.findViewById(R.id.list);
      // Create an array to specify the fields we want to display in the list
      String[] from = new String[]{KEY_LABEL_MAIN, KEY_AMOUNT};

      // and an array of the fields we want to bind those fields to 
      int[] to = new int[]{R.id.category, R.id.amount};

      // Now create a simple cursor adapter and set it to display
      mAdapter = new SplitPartAdapter(ctx, R.layout.split_part_row, null, from, to, 0,
          mTransaction.getAmount().getCurrency());
      lv.setAdapter(mAdapter);
      lv.setEmptyView(emptyView);

      LoaderManager manager = getLoaderManager();
      if (manager.getLoader(SPLIT_PART_CURSOR) != null &&
          !manager.getLoader(SPLIT_PART_CURSOR).isReset()) {
        manager.restartLoader(SPLIT_PART_CURSOR, null, this);
      } else {
        manager.initLoader(SPLIT_PART_CURSOR, null, this);
      }

    } else {
      if (mTransaction instanceof Transfer) {
        title = R.string.transfer;
        ((TextView) mLayout.findViewById(R.id.AccountLabel)).setText(R.string.transfer_from_account);
        ((TextView) mLayout.findViewById(R.id.CategoryLabel)).setText(R.string.transfer_to_account);
      } else {
        title = type ? R.string.income : R.string.expense;
      }
    }

    String amountText;
    String accountLabel = Account.getInstanceFromDb(mTransaction.accountId).label;
    if (mTransaction instanceof Transfer) {
      ((TextView) mLayout.findViewById(R.id.Account)).setText(type ? mTransaction.label : accountLabel);
      ((TextView) mLayout.findViewById(R.id.Category)).setText(type ? accountLabel : mTransaction.label);
      if (((Transfer) mTransaction).isSameCurrency()) {
        amountText = formatCurrencyAbs(mTransaction.getAmount());
      } else {
        String self = formatCurrencyAbs(mTransaction.getAmount());
        String other = formatCurrencyAbs(mTransaction.getTransferAmount());
        amountText = type == ExpenseEdit.EXPENSE ? (self + " => " + other) : (other + " => " + self);
      }
    } else {
      ((TextView) mLayout.findViewById(R.id.Account)).setText(accountLabel);
      if ((mTransaction.getCatId() != null && mTransaction.getCatId() > 0)) {
        ((TextView) mLayout.findViewById(R.id.Category)).setText(mTransaction.label);
      } else {
        mLayout.findViewById(R.id.CategoryRow).setVisibility(View.GONE);
      }
      amountText = formatCurrencyAbs(mTransaction.getAmount());
    }

    //noinspection SetTextI18n
    ((TextView) mLayout.findViewById(R.id.Date)).setText(
        DateFormat.getDateInstance(DateFormat.FULL).format(mTransaction.getDate())
            + " "
            + DateFormat.getTimeInstance(DateFormat.SHORT).format(mTransaction.getDate()));

    ((TextView) mLayout.findViewById(R.id.Amount)).setText(amountText);

    if (!mTransaction.comment.equals("")) {
      ((TextView) mLayout.findViewById(R.id.Comment)).setText(mTransaction.comment);
    } else {
      mLayout.findViewById(R.id.CommentRow).setVisibility(View.GONE);
    }

    if (!mTransaction.referenceNumber.equals("")) {
      ((TextView) mLayout.findViewById(R.id.Number)).setText(mTransaction.referenceNumber);
    } else {
      mLayout.findViewById(R.id.NumberRow).setVisibility(View.GONE);
    }

    if (!mTransaction.payee.equals("")) {
      ((TextView) mLayout.findViewById(R.id.Payee)).setText(mTransaction.payee);
      ((TextView) mLayout.findViewById(R.id.PayeeLabel)).setText(type ? R.string.payer : R.string.payee);
    } else {
      mLayout.findViewById(R.id.PayeeRow).setVisibility(View.GONE);
    }

    if (mTransaction.methodId != null) {
      ((TextView) mLayout.findViewById(R.id.Method))
          .setText(PaymentMethod.getInstanceFromDb(mTransaction.methodId).getLabel());
    } else {
      mLayout.findViewById(R.id.MethodRow).setVisibility(View.GONE);
    }

    if (Account.getInstanceFromDb(mTransaction.accountId).type.equals(Type.CASH)) {
      mLayout.findViewById(R.id.StatusRow).setVisibility(View.GONE);
    } else {
      TextView tv = (TextView) mLayout.findViewById(R.id.Status);
      tv.setBackgroundColor(mTransaction.crStatus.color);
      tv.setText(mTransaction.crStatus.toString());
    }

    if (mTransaction.originTemplate == null) {
      mLayout.findViewById(R.id.PlannerRow).setVisibility(View.GONE);
    } else {
      ((TextView) mLayout.findViewById(R.id.Plan)).setText(mTransaction.originTemplate.getPlan() == null ?
          getString(R.string.plan_event_deleted) : Plan.prettyTimeInfo(getActivity(),
          mTransaction.originTemplate.getPlan().rrule, mTransaction.originTemplate.getPlan().dtstart));
    }

    dlg.setTitle(title);
    if (doShowPicture) {
      ImageView image = ((ImageView) dlg.getWindow().findViewById(android.R.id.icon));
      image.setVisibility(View.VISIBLE);
      image.setScaleType(ImageView.ScaleType.CENTER_CROP);
      Picasso.with(ctx).load(mTransaction.getPictureUri()).fit().into(image);
    }
  }

  @NonNull
  private String formatCurrencyAbs(Money money) {
    return Utils.formatCurrency(money.getAmountMajor().abs(), money.getCurrency());
  }
}
