<?php

final class SemiStructuredObjectTypeViewController
  extends SemiStructuredObjectTypeController {

  public function handleRequest(AphrontRequest $request) {
    $viewer = $request->getViewer();
    $id = $request->getURIData('id');

    $object_type = id(new SemiStructuredObjectTypeQuery())
      ->setViewer($viewer)
      ->withIDs(array($id))
      ->executeOne();
    if (!$object_type) {
      return new Aphront404Response();
    }

    $this->setObjectType($object_type);

    $crumbs = $this->buildApplicationCrumbs();
    $title = $object_type->getName();

    $header = $this->buildHeaderView();
    $curtain = $this->buildCurtain();
    $details = $this->buildDetailsView();

    $timeline = $this->buildTransactionTimeline(
      $object_type,
      new SemiStructuredObjectTypeTransactionQuery());


    $comment_view = id(new SemiStructuredObjectTypeEditEngine())
      ->setViewer($viewer)
      ->buildEditEngineCommentView($object_type);

    list($instances_header, $instances_view) = $this->buildInstancesView();

    $view = id(new PHUITwoColumnView())
      ->setHeader($header)
      ->setCurtain($curtain)
      ->setMainColumn(array(
          $timeline,
          $comment_view,
        ))
      ->addPropertySection(pht('Description'), $details)
      ->addPropertySection($instances_header, $instances_view);


    $navigation = $this->buildSideNavView('view');

    return $this->newPage()
      ->setTitle($title)
      ->setCrumbs($crumbs)
      ->setPageObjectPHIDs(array($object_type->getPHID()))
      ->setNavigation($navigation)
      ->appendChild($view);
  }

private function buildDetailsView() {
    $viewer = $this->getViewer();
    $object_type = $this->getObjectType();

    $view = id(new PHUIPropertyListView())
      ->setUser($viewer);

    $description = $object_type->getDescription();
    if (strlen($description)) {
      $view->addTextContent(
        new PHUIRemarkupView($viewer, $description));
    }

    $custom_fields_def = $object_type->getCustomFieldsConfig();
    $custom_fields_def = id(new PhutilJSON())
      ->encodeFormatted($custom_fields_def);

    $view->addProperty(
      pht('Custom Fields'),
      phutil_tag('pre', array(), $custom_fields_def));

    return $view;
  }

  private function buildCurtain() {
    $viewer = $this->getViewer();
    $object_type = $this->getObjectType();

    $can_edit = PhabricatorPolicyFilter::hasCapability(
      $viewer,
      $object_type,
      PhabricatorPolicyCapability::CAN_EDIT);

    $can_create_instance = true;

    $id = $object_type->getID();
    $edit_uri = $this->getApplicationURI("/editclass/{$id}/");
    $create_uri = $this->getApplicationURI("/type/{$id}/new/");
    $archive_uri = $this->getApplicationURI("/type/{$id}/archive/");

    $curtain = $this->newCurtainView($object_type);

    $curtain->addAction(
      id(new PhabricatorActionView())
        ->setName(pht('Edit Object Type'))
        ->setIcon('fa-pencil')
        ->setDisabled(!$can_edit)
        ->setHref($edit_uri));

    $curtain->addAction(
      id(new PhabricatorActionView())
        ->setName(pht('Create New Instance'))
        ->setIcon('fa-plus')
        ->setDisabled(!$can_create_instance)
        ->setHref($create_uri));

    if ($object_type->isArchived()) {
      $curtain->addAction(
        id(new PhabricatorActionView())
          ->setName(pht('Activate Object Type'))
          ->setIcon('fa-check')
          ->setDisabled(!$can_edit)
          ->setWorkflow($can_edit)
          ->setHref($archive_uri));
    } else {
      $curtain->addAction(
        id(new PhabricatorActionView())
          ->setName(pht('Archive Object Type'))
          ->setIcon('fa-ban')
          ->setDisabled(!$can_edit)
          ->setWorkflow($can_edit)
          ->setHref($archive_uri));
    }

    return $curtain;
  }

  private function buildInstancesView() {
    $viewer = $this->getViewer();
    $object_type = $this->getObjectType();

    $instances = id(new SemiStructuredObjectInstanceQuery())
      ->setViewer($viewer)
      ->setLimit(10)
      ->withClassPHIDs(array($object_type->getPHID()))
      ->execute();


    $content = id(new SemiStructuredObjectInstanceSearchEngine())
      ->setViewer($viewer)
      ->renderResultsDirectly($instances);

    // $content is PhabricatorApplicationSearchResultView

    $box = new PHUIObjectBoxView();

    if ($content->getObjectList()) {
      $box->setObjectList($content->getObjectList());
    }
    if ($content->getTable()) {
      $box->setTable($content->getTable());
    }
    if ($content->getContent()) {
      $box->appendChild($content->getContent());
    }

    $header = pht('Instances of this type');

    $header = (new PHUIHeaderView())
      ->setHeader($header)
      ->addActionLink((new PHUIButtonView())
        ->setText(pht('Instances'))
        ->setIcon(SemiStructuredDataApplication::ICON_OBJECT_INSTANCE_MANY)
        ->setHref('./items/')
        ->setTag('a')
        ->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE))
      ->addActionLink((new PHUIButtonView())
        // TODO check policy
        ->setText(pht('Create New'))
        ->setIcon('fa-plus')
        ->setHref('./new/')
        ->setTag('a')
        ->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE));

    return array($header, $box);
  }

}
