package com.sharefaith.thesharefaithapp.models;

import com.appideas.base.AiDb;
import com.appideas.base.AiSTr;
import com.sharefaith.thesharefaithapp.R;
import com.sharefaith.thesharefaithapp.base.SFAppData;
import com.sharefaith.thesharefaithapp.base.SFApplication;
import com.sharefaith.thesharefaithapp.base.SFConfig;
import com.sharefaith.thesharefaithapp.base.SFCustomDownload;
import com.sharefaith.thesharefaithapp.base.SFUtil;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;

/**
 * Created by Sharefaith1 on 2014-11-02.
 */
public class SFSermonSeriesModel
{
	/**
	 * Instance of the database
	 */
	private AiDb mDb;


	/**
	 * This object's database ID
	 */
	public int mId;

	/**
	 * Preacher name
	 */
	public String mPreacher;


	/**
	 * Title
	 */
	public String mTitle;

	/**
	 * Description
	 */
	public String mDescription;

	/**
	 * This object's thumbnail location
	 */
	public String mThumbnail;

	public String mSfTag;

	public int mExternalId;

	public String mThumbnailOrigin;

	public String mShowSeriesTitle;

	public String mSermonsIncludedIn;

	/**
	 * Class constructor
	 *
	 * @since		20141021
	 */
	public SFSermonSeriesModel( int id )
	{
		if( id < 0 )
		{
			id = 0;
		}

		this.mId = id;
		this.mSfTag = "sermons";
		this.mDb = SFApplication.getInstance().getDb();
		this.refreshMembers();
	}

	public SFSermonSeriesModel()
	{
		this( 0 );
	}

	/**
	 * Refresh member variables for a specific menu item from the datasource
	 *
	 * @since		20141021
	 */
	public void refreshMembers()
	{
		this.mTitle = "";
		this.mPreacher = "";
		this.mThumbnail = "";
		this.mDescription = "";
		this.mExternalId = 0;
		this.mThumbnailOrigin = "";
		this.mShowSeriesTitle = "";
		this.mSermonsIncludedIn = "";

		if( this.mDb == null )
		{
			this.mDb = SFApplication.getInstance().getDb();
		}

		String sql =	"SELECT     COALESCE( content, '' ) as content " +
						"FROM       section_content " +
						"WHERE      id = " + this.mId;
		String[][] result = this.mDb.query( sql );
		for( int i = 0; i < result.length; i++ )
		{
			this.mTitle =  AiSTr.denullifyString( result[ i ][ 0 ] );
		}

		sql =	"SELECT     meta_key, meta_value " +
				"FROM       section_content_meta " +
				"WHERE      section_content_id = " + this.mId;
		result = this.mDb.query( sql );
		for( int i = 0; i < result.length; i++ )
		{
			String key = AiSTr.denullifyString( result[i][0] );
			String value = AiSTr.denullifyString( result[i][1] );

			if( key.equals( "thumbnail" ) )
			{
				SFConfig config = new SFConfig();

				if( value.length() > 0 )
				{
					this.mThumbnail = value;
				}
				else
				{
					this.mThumbnail = "";
				}
			}
			else if( key.equals( "preacher" ) )
			{
				this.mPreacher = value;
			}
			else if( key.equals( "description" ) )
			{
				this.mDescription = value;
			}
			else if( key.equals( "externalid" ) )
			{
				this.mExternalId = AiSTr.denullifyInt( value );
			}
			else if( key.equals( "thumbnailorigin" ) )
			{
				this.mThumbnailOrigin = value;
			}
			else if( key.equals( "includedIn" ))
			{
				this.mSermonsIncludedIn = value;
			}

		}

		this.mShowSeriesTitle = this.mTitle;
		if( this.mTitle.length() < 1 )
		{
			if( this.mPreacher.length() > 0 )
			{
				this.mShowSeriesTitle = SFApplication.getInstance().getString( R.string.all_sermons_by ) + " " + this.mPreacher;
			}
			else
			{
				this.mShowSeriesTitle = SFApplication.getInstance().getString( R.string.all_sermons );
			}
		}
	}

	/**
	 * Get instances of all series'
	 *
	 * @since		20141021
	 */
	public static SFSermonSeriesModel[] getAll()
	{
		Integer[] idArray = SFSermonSeriesModel.getAllIds();
		SFSermonSeriesModel[] items = new SFSermonSeriesModel[idArray.length];

		for( int i = 0; i < idArray.length; i++ )
		{
			items[i] = new SFSermonSeriesModel( idArray[i] );
		}

		return items;
	}

	/**
	 * Get the ID for all series'
	 *
	 * @since		20141021
	 */
	public static Integer[] getAllIds()
	{
		AiDb db = SFApplication.getInstance().getDb();
		SFSermonSeriesModel baseModel = new SFSermonSeriesModel();

		String sql =	"SELECT     id " +
						"FROM       section_content " +
						"WHERE      ondevice_section_id = " +
						"			(SELECT id FROM ondevice_sections WHERE sf_tag = '" + baseModel.mSfTag + "') AND " +
						"			parent_id = 0 " +
						"ORDER BY	position_index DESC";
		String[][] result = db.query( sql );
		Integer[] returnValue = new Integer[result.length];
		for( int i = 0; i < result.length; i++ )
		{
			returnValue[i] =  AiSTr.denullifyInt( result[ i ][ 0 ] );
		}

		return returnValue;
	}

	/**
	 * Refresh member variables for a specific menu item from the datasource
	 *
	 * @since		20141021
	 */
	public SFSermonModel[] sermonsForSeries()
	{
		int count = 0;

		String sql =	" SELECT     id " +
						" FROM       section_content " +
						" WHERE      id IN " +
						"	(SELECT sermon_section_content_id FROM sermon_to_playlist WHERE playlist_section_content_id = " + this.mId + ") " +
						" ORDER BY	position_index DESC ";
		String[][] result = this.mDb.query( sql );
		//Log.d("mTag","mId = " + this.mId);
		//Log.d( "mTag", "results length = " + result.length );
		SFSermonModel[] tempReturnValue = new SFSermonModel[result.length];
		for( int i = 0; i < result.length; i++ )
		{
			SFSermonModel sermon = new SFSermonModel( AiSTr.denullifyInt( result[ i ][ 0 ] ) );
			//Log.d( "mTag","sermon[" + i + "} = " +sermon.mId );
			// weed out sermons that are not visible
			if( sermon.mIsVisible )
			{
				tempReturnValue[count] = sermon;
				count++;
			}
		}

		SFSermonModel[] returnValue = Arrays.copyOfRange( tempReturnValue, 0, count );

		return returnValue;
	}

	/**
	 * Get a model object from its external object ID
	 *
	 */
	public static SFSermonSeriesModel objectFromExternalId( int externalId )
	{
		SFSermonSeriesModel model = new SFSermonSeriesModel( 0 );

		AiDb db = SFApplication.getInstance().getDb();

		String sql =	"SELECT     section_content.id AS id " +
						"FROM       section_content, section_content_meta " +
						"WHERE      section_content.ondevice_section_id = " +
						"				(SELECT id FROM ondevice_sections WHERE sf_tag = '" + model.mSfTag + "') AND " +
						"			section_content.parent_id = 0 AND " +
						"			section_content_meta.section_content_id = section_content.id AND " +
						"			section_content_meta.meta_key = 'externalid' AND " +
						"			section_content_meta.meta_value = " + externalId;
		String[][] result = db.query( sql );
		for( int i = 0; i < result.length; i++ )
		{
			int id =  AiSTr.denullifyInt( result[ i ][ 0 ] );
			model = new SFSermonSeriesModel( id );
		}

		return model;
	}

	public void saveMembers( boolean replaceThumbnail )
	{
		boolean isNew = false;
		if( this.mId == 0 )
		{
			isNew = true;
			this.mId = this.mDb.insertBlank( "section_content", "id" );
		}

		String sql =
				"UPDATE		section_content " +
				" SET		content = '" + AiSTr.dbEscape( this.mTitle ) + "', " +
						"	position_index = " + SFUtil.currentTimestamp() + ", " +
				"			ondevice_section_id = " +
				"				( SELECT id FROM ondevice_sections WHERE sf_tag = 'sermons' ) " +
				" WHERE		id = " + this.mId;
		this.mDb.noReturnQuery( sql );

		String keys[] = { "preacher", "thumbnail", "thumbnailorigin", "externalid", "includedIn" };

		if( isNew )
		{
			//Log.d( "mTag","Hit new playlist" );
			for( int i = 0; i < keys.length; i++ )
			{
				String prepSql =
						"INSERT INTO	section_content_meta " +
						"				( section_content_id, meta_key, meta_value ) " +
						"VALUES			( " + this.mId + ", '" + keys[i] + "', '' )";
				this.mDb.noReturnQuery( prepSql );
			}
			sql =
					"UPDATE			section_content " +
							" SET	position_index = " + SFUtil.currentTimestamp() + " " +
							" WHERE	id = " + this.mId;
			this.mDb.noReturnQuery( sql );
		}

		HashMap<String,String> input = new HashMap<String,String>();
		input.put( "preacher", this.mPreacher );
		input.put( "thumbnail", this.mThumbnail );
		input.put( "thumbnailorigin", this.mThumbnailOrigin );
		input.put( "externalid", String.valueOf( this.mExternalId ) );
		input.put( "includedIn", this.mSermonsIncludedIn );

		for( HashMap.Entry<String,String> map : input.entrySet() )
		{
			sql =
					"UPDATE		section_content_meta " +
					"SET		meta_value = '" + AiSTr.dbEscape( map.getValue() ) + "' " +
					"WHERE		section_content_id = " + this.mId + " AND " +
					"			meta_key = '" + map.getKey() + "' ";
			this.mDb.noReturnQuery( sql );
		}

		if( replaceThumbnail )
		{
			SFCustomDownload download = new SFCustomDownload();
			String filename = "";
			try
			{
				filename = download.downloadFile( this.mThumbnailOrigin );
			}
			catch( Exception e )
			{
				// If we got an exception, we just record empty file
				filename = "";
			}

			sql =
					"UPDATE		section_content_meta " +
					"SET		meta_value = '" + filename + "' " +
					"WHERE		section_content_id = " + this.mId + " AND " +
					"			meta_key = 'thumbnail' ";
			this.mDb.noReturnQuery( sql );

		} // if( replaceThumbnail )

		//update playlist_to_section
		sql =
				" DELETE FROM playlist_to_section " +
						" WHERE playlist_section_content_id = " + this.mId;
		this.mDb.noReturnQuery( sql );

		Integer[] includedIn = SFApplication.getInstance().parseIncludedIn( this.mSermonsIncludedIn );

		for( int i = 0; i < includedIn.length; i ++ )
		{
			sql =
					" INSERT INTO playlist_to_section " +
							" ( playlist_section_content_id, ondevice_section_id ) " +
							" VALUES ( " + this.mId + ", (SELECT id FROM ondevice_sections WHERE external_id = " + includedIn[i] + "))";
			this.mDb.noReturnQuery( sql );
		}

	} // public void saveMembers( boolean replaceThumbnail )

	public static Integer[] seriesIdsFromPreacherAndSeries( String preacher, String series )
	{
		SFSermonSeriesModel[] allSeries = SFSermonSeriesModel.getAll();

		Integer[] matchedSeriesIds = new Integer[allSeries.length];
		int matchCount = 0;

		for( int i = 0; i < allSeries.length; i++ )
		{
			SFSermonSeriesModel thisSeries = allSeries[i];
			// preacher and series are empty
			if( thisSeries.mPreacher.length() < 1 && thisSeries.mTitle.length() < 1 )
			{
				matchedSeriesIds[matchCount] = thisSeries.mId;
				matchCount++;
			}
			else
			{
				boolean preacherMatch = thisSeries.mPreacher.toLowerCase().equals( preacher.toLowerCase() );
				boolean seriesMatch = thisSeries.mTitle.toLowerCase().equals( series.toLowerCase() );

				if( thisSeries.mPreacher.length() > 0 && thisSeries.mTitle.length() > 0 )
				{
					if( preacherMatch && seriesMatch )
					{
						matchedSeriesIds[ matchCount ] = thisSeries.mId;
						matchCount++;
					}
				}
				else if( thisSeries.mPreacher.length() > 0 && preacherMatch )
				{
					matchedSeriesIds[ matchCount ] = thisSeries.mId;
					matchCount++;
				}
				else if( thisSeries.mTitle.length() > 0 && seriesMatch )
				{
					matchedSeriesIds[ matchCount ] = thisSeries.mId;
					matchCount++;
				}
			}
		} // for( int i = 0; i < allSeries.length; i++ )


		Integer[] returnValue = new Integer[matchCount];

		for( int i = 0; i < matchCount; i++ )
		{
			returnValue[i] = matchedSeriesIds[i];
			//Log.d("mTag", "seriesIdFromPreacherAndSeries returnValue " + i + " = " + returnValue[i]);
		}

		return returnValue;
	}

	public void remove()
	{
		SFConfig config = new SFConfig();

		if( this.mThumbnail.length() > 0 )
		{
			String filePath = config.mCustomAssetPath + this.mThumbnail;
			File file = new File( filePath );
			file.delete();
		}

		String sql =
				"DELETE FROM sermon_to_playlist " +
						" WHERE playlist_section_content_id = " + this.mId;
		this.mDb.noReturnQuery( sql );

		sql =
				"DELETE FROM	section_content_meta " +
				"WHERE			section_content_id = " + this.mId;
		this.mDb.noReturnQuery( sql );

		sql =
			"DELETE FROM	section_content " +
			"WHERE			id = " + this.mId;
		this.mDb.noReturnQuery( sql );

		sql =
				"DELETE FROM playlist_to_section " +
						" WHERE playlist_section_content_id = " + this.mId;
		this.mDb.noReturnQuery( sql );
	}

	public void saveHashValue()
	{
		SFAppData appData = new SFAppData();
		String returnValue = calculateHashValue();

		String sql =
				"DELETE FROM sync_objects " +
						" WHERE sync_object_id = " + mExternalId +
						" AND object_type = 'playlist'";
		mDb.noReturnQuery( sql );

		sql =
				"INSERT INTO sync_objects " +
						"( sync_object_id, hash_value, object_type ) " +
						"VALUES ( " + mExternalId + ", '" + returnValue + "', 'playlist' )"
		;
		mDb.noReturnQuery( sql );

		appData.hashImage( mExternalId );
	}

	public String calculateHashValue()
	{
		String stingToHash = mTitle + mPreacher + mThumbnailOrigin + mSermonsIncludedIn;
		//Log.d("mTag","Playlist string to hash = " + stingToHash);
		return SFUtil.md5( stingToHash );
	}
}
