<?php

declare(strict_types=1);

namespace pictpostpersonal\model;

use Exception;
use PDO;
use pictpostpersonal\Environment;
use pictpostpersonal\SQL;
use pictpostpersonal\SQLiteCRUD;

/**
 * SNSアカウントへのリンク情報を管理するクラス
 */
class Account
{
    private SQLiteCRUD $sql_crud;

    /**
     * コンストラクタ
     *
     * @param PDO $db データベース接続オブジェクト
     */
    public function __construct(PDO $db)
    {
        $this->sql_crud = new SQLiteCRUD($db);
    }

    /**
     * アカウント情報格納用のテーブルを生成する
     *
     * @return void
     */
    public static function initialize(SQLiteCRUD $sql_crud)
    {
        $sql_crud->table('accounts')->createTable(
            [
                SQL::Id('id'),
                SQL::Text('url'),
                SQL::Text('icon'),
                SQL::Integer('type', "0")
            ]
        );
    }

    /**
     * すべてのアカウント情報を取得する
     *
     * @return array アカウントの一覧
     */
    public function findAll(): array
    {
        $accounts = $this->sql_crud->table('accounts')->fetch();

        foreach ($accounts as $index => $item) {
            $icon_type = $item['type'];
            $accounts[$index]['icon_type'] = $icon_type;
            if ($icon_type == 0) {
                $accounts[$index]['icon_html'] = "<a href=\"{$accounts[$index]['url']}\" target=\"_blank\"><i class=\"{$accounts[$index]['icon']} p-sns-icon\"></i></a>";
            } else {
                $base_url = Environment::getSiteUrl();
                $accounts[$index]['icon_html'] = "<a href=\"{$accounts[$index]['url']}\" target=\"_blank\"><img src=\"{$base_url}/images/{$accounts[$index]['icon']}\" class=\"p-sns-icon\" width=32 height=32 target=\"_blank\"></a>";
            }
        }

        return $accounts;
    }

    /**
     * 新しいアカウントを作成する
     *
     * @param string $url  アカウントのURL
     * @param string $icon アカウントのアイコンURLまたはパス
     * @return int 作成されたアカウントのID
     *
     * @throws Exception データベース操作に失敗した場合
     */
    public function create(string $url, string $icon, string $type = '0'): int
    {
        $data = [
            'url'  => $url,
            'icon' => $icon,
            'type' => $type
        ];

        $result_id = $this->sql_crud->table('accounts')->create($data);

        if ($result_id === false) {
            throw new Exception('アカウントの作成に失敗しました。');
        }

        return $result_id;
    }

    /**
     * 既存のアカウント情報を更新する
     *
     * @param int    $id    更新対象のアカウントID
     * @param string $url   新しいURL
     * @param string $icon  新しいアイコンURLまたはパス
     * @return void
     *
     * @throws Exception アカウントが存在しない場合
     */
    public function update($id, string $url, string $icon, string $type = '0'): void
    {
        $data = [
            'url'  => $url,
            'icon' => $icon,
            'type' => $type
        ];

        $affected_rows = $this->sql_crud->table('accounts')->where('id = :id', ['id' => $id])->update($data);

        if ($affected_rows === 0) {
            throw new Exception('指定されたアカウントが存在しません。');
        }
    }

    /**
     * 指定されたIDのアカウントを削除する
     *
     * @param int $id 削除対象のアカウントID
     * @return void
     *
     * @throws Exception アカウントが存在しない場合
     */
    public function delete($id): void
    {
        $affected_rows = $this->sql_crud->table('accounts')->delete($id);

        if ($affected_rows === 0) {
            throw new Exception('指定されたアカウントが存在しません。');
        }
    }

    /**
     * すべてのアカウントを削除し、IDをリセットする
     *
     * @return void
     */
    public function clear(): void
    {
        $this->sql_crud->table('accounts')->delete();
        $this->sql_crud->table('accounts')->reseed();
    }
}
