<?php

/**
 * Class TB_Shared_Ent_TeamData_Contract
 *
 * @property integer $id
 * @property integer $profile_id
 * @property array $profile_data_js
 * @property integer $team_id
 * @property array $contractee_data_js
 * @property string $name
 * @property string $type
 * @property integer $current_price_factor
 * @property integer $max_price_factor
 * @property string $currency
 * @property integer $price
 * @property integer $price_payed
 * @property string $start_date
 * @property string $end_date
 * @property string $payment_due_date
 * @property string|NULL $admin_note
 * @property string $state
 * @property DateTime $last_updated_dt
 * @property DateTime $created_dt
 */
class TB_Shared_Ent_TeamData_Contract extends Francis_Db_Row
{
    public static function getForOverview( $teamId )
    {
        $beginDate = date('Y-m-d', strtotime('-30 day' ) );
        $nowDate = date('Y-m-d', strtotime( '+1 day' ) );

        $sql = 'SELECT * FROM ' . self::getTable() . ' WHERE team_id = :team_id AND ';
        $sql .= "state = 'active' AND ";
        $sql .= '( ';
        $sql .= '( start_date >= :begin_date AND end_date <= :now_date ) OR ';
        $sql .= '( end_date >= :begin_date AND end_date <= :now_date ) OR ';
        $sql .= '( created_dt >= :begin_date AND created_dt <= :now_date ) ';
        $sql .= ') ';
        $sql .= 'ORDER BY `start_date` ASC';

        return self::findMany(
            $sql,
            array(
                ':team_id' => $teamId,
                ':begin_date' => $beginDate,
                ':now_date' => $nowDate
            )
        );
    }

    public static function getCountForTeamId( $teamId )
    {
        $dbh = self::getDbh();
        $sqlArgs = array( ':team_id' => $teamId );
        $sql  = 'SELECT COUNT(id) AS cnt FROM ' . self::getTable() . ' ';
        $sql .= 'WHERE team_id = :team_id ';
        $sql .= "AND state = 'active' ";

        $stmt = $dbh->prepare( $sql );
        $stmt->execute( $sqlArgs );
        $res = $stmt->fetch( PDO::FETCH_COLUMN );
        return $res;
    }

    public static function getCountOpenForTeamId( $teamId )
    {
        $dbh = self::getDbh();
        $sqlArgs = array( ':team_id' => $teamId );
        $sql  = 'SELECT COUNT(id) AS cnt FROM ' . self::getTable() . ' ';
        $sql .= 'WHERE team_id = :team_id AND ';
        $sql .= 'start_date < NOW() AND end_date > NOW() AND ';
        $sql .= "state = 'active' ";

        $stmt = $dbh->prepare( $sql );
        $stmt->execute( $sqlArgs );
        $res = $stmt->fetch( PDO::FETCH_COLUMN );
        return $res;
    }

    public static function getCountOpenPaymentsForTeamId( $teamId )
    {
        $dbh = self::getDbh();
        $sqlArgs = array( ':team_id' => $teamId );
        $sql  = 'SELECT COUNT(id) AS cnt FROM ' . self::getTable() . ' ';
        $sql .= 'WHERE team_id = :team_id AND ';
        $sql .= 'price > price_payed AND ';
        $sql .= "state = 'active' ";

        $stmt = $dbh->prepare( $sql );
        $stmt->execute( $sqlArgs );
        $res = $stmt->fetch( PDO::FETCH_COLUMN );
        return $res;
    }

    public static function getSumOpenPaymentsForTeamId( $teamId )
    {
        $dbh = self::getDbh();
        $sqlArgs = array( ':team_id' => $teamId );
        $sql  = 'SELECT ( SUM( price ) - SUM( price_payed ) ) AS open_sum FROM ' . self::getTable() . ' ';
        $sql .= 'WHERE team_id = :team_id AND ';
        $sql .= "state = 'active' AND ";
        $sql .= 'price > price_payed ';

        $stmt = $dbh->prepare( $sql );
        $stmt->execute( $sqlArgs );
        $res = $stmt->fetch( PDO::FETCH_COLUMN );
        return (int)$res;
    }

    public static function getCountOpenAttendancesToChargeForTeamId( $teamId )
    {
        $dbh = self::getDbh();
        $sqlArgs = array( ':team_id' => $teamId );
        $sql  = 'SELECT COUNT( a.id ) AS cnt FROM attendee AS a ';
        $sql .= 'LEFT JOIN appointment AS app ON app.id = a.appointment_id ';
        $sql .= 'WHERE app.team_id = :team_id AND ';
        $sql .= 'app.start_dt < NOW() AND ';
        $sql .= 'app.state = "open" AND ';
        $sql .= 'a.contract_id IS NULL AND ';
        $sql .= 'a.has_attended = "attended" ';

        $stmt = $dbh->prepare( $sql );
        $stmt->execute( $sqlArgs );
        $res = $stmt->fetch( PDO::FETCH_COLUMN );
        return (int)$res;
    }

    public static function getAllForTeamId( $teamId, $profileId = NULL, $state = 'active' )
    {
        $sql  = 'SELECT * FROM ' . self::getTable() . ' WHERE team_id = :team_id ';
        if ( !is_null( $profileId ) )
        {
            $sql .= 'AND profile_id = :profile_id ';
        }
        $sql .= 'AND state = :state ';
        $sql .= 'ORDER BY `created_dt` DESC';

        if ( !is_null( $profileId ) )
        {
            return self::findMany( $sql, array( ':team_id' => $teamId, ':profile_id' => $profileId, ':state' => $state ) );
        }
        else
        {
            return self::findMany( $sql, array( ':team_id' => $teamId, ':state' => $state ) );
        }
    }

    public static function getAllForProfileId( $profileId )
    {
        $sql  = 'SELECT * FROM ' . self::getTable() . ' WHERE profile_id = :profile_id ';
        return self::findMany( $sql, array( ':profile_id' => $profileId ) );
    }

    public static function getAllForTeamIdWithOpenClaims( $teamId )
    {
        $sql  = 'SELECT * FROM ' . self::getTable() . ' WHERE team_id = :team_id ';
        $sql .= 'AND state = "active" ';
        $sql .= 'AND price > price_payed ';
        $sql .= 'ORDER BY `payment_due_date` DESC';
        return self::findMany( $sql, array( ':team_id' => $teamId ) );
    }

    public static function getUnchargedProfileIdsForTeam( $teamId )
    {
        $sql  = 'SELECT a.profile_id, COUNT(a.profile_id) AS cnt FROM `attendee` AS `a` ';
        $sql .= 'LEFT JOIN appointment AS `app` ON app.id = a.appointment_id WHERE app.team_id = :team_id ';
        $sql .= "AND app.state = 'open' ";
        $sql .= 'AND app.start_dt < NOW() ';
        $sql .= 'AND a.has_attended = "attended" AND a.contract_id IS NULL GROUP BY a.profile_id';

        $dbh = self::getDbh();

        $stmt = $dbh->prepare( $sql );
        $stmt->execute( array( ':team_id' => $teamId ) );
        $rows = $stmt->fetchAll( PDO::FETCH_ASSOC );

        return $rows;
    }

    public static function updateCurrentPriceFactorByContractId( $contractId )
    {
        $dbh = self::getDbh();
        $appIds = TB_Shared_Ent_TeamData_Attendee::getAppointmentIdsForContractId( $contractId );
        $sumPriceFactor = 0;

        if ( 0 < count( $appIds ) )
        {
            $in = str_repeat('?,', count( $appIds ) - 1 ) . '?';
            $sql  = "SELECT SUM( price_factor ) AS `current_total` FROM `appointment` WHERE ";
            $sql .= "id IN ( $in )";
            $stmt = $dbh->prepare( $sql );
            $stmt->execute( $appIds );
            $rowSum  = $stmt->fetch( PDO::FETCH_ASSOC );
            $sumPriceFactor = $rowSum[ 'current_total' ];
        }

        $contract = TB_Shared_Ent_TeamData_Contract::get( $contractId );
        if ( $contract )
        {
            $contract->current_price_factor = $sumPriceFactor;
            $contract->save();
        }
    }

    public static function deleteAllByTeamId( $teamId )
    {
        $sql = 'DELETE FROM ' . self::getTable() . ' WHERE team_id = :team_id';
        return self::execute( $sql, array( ':team_id' => $teamId ) );

    }

    /**
     * Called during deletion
     */
    public function deleteReferences()
    {
        TB_Shared_Ent_TeamData_Attendee::removeContractId( $this->id );
    }

    /**
     * Return table name
     *
     * @return null|string
     */
    public static function getTable()
    {
        return 'contract';
    }

    /**
     * Return db handler
     *
     * @return Francis_Db_MySql|null
     */
    public static function getDbh()
    {
        return TB_Shared_Db_TeamData::get();
    }
}