// yt - A fully featured command line YouTube client
//
// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This file is part of Yt.
//
// You should have received a copy of the License along with this program.
// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.

use std::fmt::Display;

pub trait FormatVideo {
    type Output;

    fn cache_path(&self) -> Self::Output;
    fn description(&self) -> Self::Output;
    fn duration(&self) -> Self::Output;
    fn extractor_hash(&self) -> Self::Output;
    fn last_status_change(&self) -> Self::Output;
    fn parent_subscription_name(&self) -> Self::Output;
    fn priority(&self) -> Self::Output;
    fn publish_date(&self) -> Self::Output;
    fn status(&self) -> Self::Output;
    fn status_change(&self) -> Self::Output;
    fn thumbnail_url(&self) -> Self::Output;
    fn title(&self) -> Self::Output;
    fn url(&self) -> Self::Output;
    fn video_options(&self) -> Self::Output;

    fn to_parts(
        &self,
    ) -> (
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
        Self::Output,
    ) {
        let cache_path = self.cache_path();
        let description = self.description();
        let duration = self.duration();
        let extractor_hash = self.extractor_hash();
        let last_status_change = self.last_status_change();
        let parent_subscription_name = self.parent_subscription_name();
        let priority = self.priority();
        let publish_date = self.publish_date();
        let status = self.status();
        let status_change = self.status_change();
        let thumbnail_url = self.thumbnail_url();
        let title = self.title();
        let url = self.url();
        let video_options = self.video_options();

        (
            cache_path,
            description,
            duration,
            extractor_hash,
            last_status_change,
            parent_subscription_name,
            priority,
            publish_date,
            status,
            status_change,
            thumbnail_url,
            title,
            url,
            video_options,
        )
    }

    fn to_info_display(&self) -> String
    where
        <Self as FormatVideo>::Output: Display,
    {
        let (
            cache_path,
            description,
            duration,
            extractor_hash,
            last_status_change,
            parent_subscription_name,
            priority,
            publish_date,
            status,
            status_change,
            thumbnail_url,
            title,
            url,
            video_options,
        ) = self.to_parts();

        let status_change = if status_change.to_string().as_str() == "false" {
            "currently not changing"
        } else if status_change.to_string().as_str() == "true" {
            "currently changing"
        } else {
            unreachable!("This is an formatted boolean");
        };

        let string = format!(
            "\
{title} ({extractor_hash})
| -> {cache_path}
| -> {duration}
| -> {parent_subscription_name}
| -> priority: {priority}
| -> {publish_date}
| -> status: {status} since {last_status_change}
| -> {status_change}
| -> {thumbnail_url}
| -> {url}
| -> options: {}
{description}\n",
            video_options.to_string().trim()
        );
        string
    }

    fn to_line_display(&self) -> String
    where
        Self::Output: Display,
    {
        let f = format!(
            "{} {} {} {} {} {}",
            self.status(),
            self.extractor_hash(),
            self.title(),
            self.publish_date(),
            self.parent_subscription_name(),
            self.duration()
        );

        f
    }

    fn to_select_file_display(&self) -> String
    where
        Self::Output: Display,
    {
        let f = format!(
            r#"{}{} {} "{}" "{}" "{}" "{}" "{}"{}"#,
            self.status(),
            self.video_options(),
            self.extractor_hash(),
            self.title(),
            self.publish_date(),
            self.parent_subscription_name(),
            self.duration(),
            self.url(),
            '\n'
        );

        f
    }
}